diff --git a/.gradle/5.1.1/executionHistory/executionHistory.bin b/.gradle/5.1.1/executionHistory/executionHistory.bin
deleted file mode 100644
index 437b3009d041d4185d9ad82619c3707a4099a9f3..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/executionHistory/executionHistory.bin and /dev/null differ
diff --git a/.gradle/5.1.1/executionHistory/executionHistory.lock b/.gradle/5.1.1/executionHistory/executionHistory.lock
deleted file mode 100644
index 4cc29f6c9d28d762e41a720ab4cfc8433340513b..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/executionHistory/executionHistory.lock and /dev/null differ
diff --git a/.gradle/5.1.1/fileChanges/last-build.bin b/.gradle/5.1.1/fileChanges/last-build.bin
deleted file mode 100644
index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/fileChanges/last-build.bin and /dev/null differ
diff --git a/.gradle/5.1.1/fileContent/fileContent.lock b/.gradle/5.1.1/fileContent/fileContent.lock
deleted file mode 100644
index cf35d6e2bb81b7d45e6608f23e7f02f6dce09fe3..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/fileContent/fileContent.lock and /dev/null differ
diff --git a/.gradle/5.1.1/fileHashes/fileHashes.bin b/.gradle/5.1.1/fileHashes/fileHashes.bin
deleted file mode 100644
index d2346e1ebf1429d4ee285c87198f270d7a51fe7c..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/fileHashes/fileHashes.bin and /dev/null differ
diff --git a/.gradle/5.1.1/fileHashes/fileHashes.lock b/.gradle/5.1.1/fileHashes/fileHashes.lock
deleted file mode 100644
index 05b325821a1d4e41152bad71597a774282ab836d..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/fileHashes/fileHashes.lock and /dev/null differ
diff --git a/.gradle/5.1.1/fileHashes/resourceHashesCache.bin b/.gradle/5.1.1/fileHashes/resourceHashesCache.bin
deleted file mode 100644
index 7fab46a35b38bfe377714770e7fc10d2fbeae0e2..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/fileHashes/resourceHashesCache.bin and /dev/null differ
diff --git a/.gradle/5.1.1/gc.properties b/.gradle/5.1.1/gc.properties
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/.gradle/5.1.1/javaCompile/classAnalysis.bin b/.gradle/5.1.1/javaCompile/classAnalysis.bin
deleted file mode 100644
index 5ac5af7fcf2dc902eed2108b080b192d3e4f07da..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/javaCompile/classAnalysis.bin and /dev/null differ
diff --git a/.gradle/5.1.1/javaCompile/javaCompile.lock b/.gradle/5.1.1/javaCompile/javaCompile.lock
deleted file mode 100644
index 849213ddabddfb5fe57b928bb5fe1c628803bdca..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/javaCompile/javaCompile.lock and /dev/null differ
diff --git a/.gradle/5.1.1/javaCompile/taskHistory.bin b/.gradle/5.1.1/javaCompile/taskHistory.bin
deleted file mode 100644
index 9153ac4f396eb686ae998b57f6739fe8da0bda94..0000000000000000000000000000000000000000
Binary files a/.gradle/5.1.1/javaCompile/taskHistory.bin and /dev/null differ
diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock
deleted file mode 100644
index 984a487ea31522b03cd99fbf74813ac0c4243c8a..0000000000000000000000000000000000000000
Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and /dev/null differ
diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties
deleted file mode 100644
index 43b3be926c4e7a1214d4e52c7f10a4e37ddfc0e1..0000000000000000000000000000000000000000
--- a/.gradle/buildOutputCleanup/cache.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-#Fri May 03 16:55:06 CST 2019
-gradle.version=5.1.1
diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin
deleted file mode 100644
index bb550e4d54e8a7698211b00f5cd29abf4f0a827a..0000000000000000000000000000000000000000
Binary files a/.gradle/buildOutputCleanup/outputFiles.bin and /dev/null differ
diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
deleted file mode 100644
index ded04d1e422eb1aef89958c0c95f16839b50123b..0000000000000000000000000000000000000000
Binary files a/.idea/caches/build_file_checksums.ser and /dev/null differ
diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser
deleted file mode 100644
index 0c29fc5fc9f909826834560919ab09d6a74f3878..0000000000000000000000000000000000000000
Binary files a/.idea/caches/gradle_models.ser and /dev/null differ
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..681f41ae2aee4749eb4ddda94f8c6a76c825c825
--- /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
deleted file mode 100644
index 2996d531255e06fae876df257e8237225a4906b7..0000000000000000000000000000000000000000
--- a/.idea/gradle.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d39fcfa58d3d2767a5c51da6c395fc45b0b2dd16
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__android_arch_core_common_1_1_1_jar.xml b/.idea/libraries/Gradle__android_arch_core_common_1_1_1_jar.xml
deleted file mode 100644
index 684672f09293ad65712673a519315bf2e9809559..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__android_arch_core_common_1_1_1_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__android_arch_core_runtime_1_1_1_aar.xml b/.idea/libraries/Gradle__android_arch_core_runtime_1_1_1_aar.xml
deleted file mode 100644
index cc48dd331d4b8c3519b0fefa878af47bdd4aa0a9..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__android_arch_core_runtime_1_1_1_aar.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__android_arch_lifecycle_common_1_1_1_jar.xml b/.idea/libraries/Gradle__android_arch_lifecycle_common_1_1_1_jar.xml
deleted file mode 100644
index 1f4527689b5400f71e5d432aa2d0f115788467b8..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__android_arch_lifecycle_common_1_1_1_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__android_arch_lifecycle_livedata_1_1_1_aar.xml b/.idea/libraries/Gradle__android_arch_lifecycle_livedata_1_1_1_aar.xml
deleted file mode 100644
index ff6ee418cb930b81ece402e1543dec7b1b462e5f..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__android_arch_lifecycle_livedata_1_1_1_aar.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__android_arch_lifecycle_livedata_core_1_1_1_aar.xml b/.idea/libraries/Gradle__android_arch_lifecycle_livedata_core_1_1_1_aar.xml
deleted file mode 100644
index a51bad3a870b4bfd99b4d1cc5a47b90e59f33c70..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__android_arch_lifecycle_livedata_core_1_1_1_aar.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__android_arch_lifecycle_runtime_1_1_1_aar.xml b/.idea/libraries/Gradle__android_arch_lifecycle_runtime_1_1_1_aar.xml
deleted file mode 100644
index ca4a1fe25f4f062df2df2feda5d8b4169b8c8fa6..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__android_arch_lifecycle_runtime_1_1_1_aar.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__android_arch_lifecycle_viewmodel_1_1_1_aar.xml b/.idea/libraries/Gradle__android_arch_lifecycle_viewmodel_1_1_1_aar.xml
deleted file mode 100644
index a27b78d06058bb334b55200fd7d326db3c6b42df..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__android_arch_lifecycle_viewmodel_1_1_1_aar.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_animated_vector_drawable_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_animated_vector_drawable_28_0_0_aar.xml
deleted file mode 100644
index 6601585ba9342f1e5ac83ed84dc87026726986bc..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_animated_vector_drawable_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_appcompat_v7_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_appcompat_v7_28_0_0_aar.xml
deleted file mode 100644
index 7257628408dc58d0ad8872b95fba67c8d387b039..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_appcompat_v7_28_0_0_aar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_asynclayoutinflater_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_asynclayoutinflater_28_0_0_aar.xml
deleted file mode 100644
index 16ad14d3c424f2345763cbb3f6d78d750d0b802a..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_asynclayoutinflater_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_collections_28_0_0_jar.xml b/.idea/libraries/Gradle__com_android_support_collections_28_0_0_jar.xml
deleted file mode 100644
index 6539ea51d7dc2070bc99e18231c21dfeb8eabd81..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_collections_28_0_0_jar.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_constraint_constraint_layout_1_1_3_aar.xml b/.idea/libraries/Gradle__com_android_support_constraint_constraint_layout_1_1_3_aar.xml
deleted file mode 100644
index 692c2044864c3a7b98297f04c65c006de833dc7c..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_constraint_constraint_layout_1_1_3_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_constraint_constraint_layout_solver_1_1_3_jar.xml b/.idea/libraries/Gradle__com_android_support_constraint_constraint_layout_solver_1_1_3_jar.xml
deleted file mode 100644
index 484f71da1d976435bd5122268c418a8de790f96a..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_constraint_constraint_layout_solver_1_1_3_jar.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_coordinatorlayout_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_coordinatorlayout_28_0_0_aar.xml
deleted file mode 100644
index de7eae0f73dc652a12eef397089313ba0b7ebafe..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_coordinatorlayout_28_0_0_aar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_cursoradapter_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_cursoradapter_28_0_0_aar.xml
deleted file mode 100644
index 4fa7de14dbb35437daddf98177eb8bd7b18d1ca1..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_cursoradapter_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_customview_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_customview_28_0_0_aar.xml
deleted file mode 100644
index 016926853186a18a2470ee7e0a27bfc19c4b8892..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_customview_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_documentfile_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_documentfile_28_0_0_aar.xml
deleted file mode 100644
index 55252388dd9eef641a7788d12062273039c20eb2..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_documentfile_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_drawerlayout_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_drawerlayout_28_0_0_aar.xml
deleted file mode 100644
index 0569c190e7f863347c3ec6b9fb4f166aa77dd114..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_drawerlayout_28_0_0_aar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_interpolator_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_interpolator_28_0_0_aar.xml
deleted file mode 100644
index 8df48d09cff7accc74708b64da4bbfc601dac7c2..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_interpolator_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_loader_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_loader_28_0_0_aar.xml
deleted file mode 100644
index e1b3ace0a6f48cb0862255cd81a4f3c8e86e5acf..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_loader_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_localbroadcastmanager_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_localbroadcastmanager_28_0_0_aar.xml
deleted file mode 100644
index e561b9533f1e2156e4d5e9a16299b44ed8ec6a6b..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_localbroadcastmanager_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_print_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_print_28_0_0_aar.xml
deleted file mode 100644
index 6f8ec58852eea8621f4bef24bd041137cb092798..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_print_28_0_0_aar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_slidingpanelayout_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_slidingpanelayout_28_0_0_aar.xml
deleted file mode 100644
index ee9d1f01e834746bc488cad22b785e692700a161..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_slidingpanelayout_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_support_annotations_28_0_0_jar.xml b/.idea/libraries/Gradle__com_android_support_support_annotations_28_0_0_jar.xml
deleted file mode 100644
index a127e59fba64fe3da1c0ed647635c1b77719fbde..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_support_annotations_28_0_0_jar.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_support_compat_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_support_compat_28_0_0_aar.xml
deleted file mode 100644
index 3a33de9aa9ff051256ea75dddfd36b6b92b0ca64..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_support_compat_28_0_0_aar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_support_core_ui_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_support_core_ui_28_0_0_aar.xml
deleted file mode 100644
index 5758e865ea3e389943f598f5938adcea6ba67f63..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_support_core_ui_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_support_core_utils_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_support_core_utils_28_0_0_aar.xml
deleted file mode 100644
index db603ec804fe7fca1fb2c5a398086dbe46dba3b0..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_support_core_utils_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_support_fragment_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_support_fragment_28_0_0_aar.xml
deleted file mode 100644
index 7b82bb2c81db970536e1f459511029aea7d07a15..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_support_fragment_28_0_0_aar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_support_vector_drawable_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_support_vector_drawable_28_0_0_aar.xml
deleted file mode 100644
index 005c54b4ed07255bae74ef8f56c2e5c87a789e24..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_support_vector_drawable_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_swiperefreshlayout_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_swiperefreshlayout_28_0_0_aar.xml
deleted file mode 100644
index fd60a5ed0f9c9b05beaddf6873be2646901c9236..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_swiperefreshlayout_28_0_0_aar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_test_espresso_espresso_core_3_0_2_aar.xml b/.idea/libraries/Gradle__com_android_support_test_espresso_espresso_core_3_0_2_aar.xml
deleted file mode 100644
index 2c854112974b5aa29408028101ecce7ea67a4329..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_test_espresso_espresso_core_3_0_2_aar.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_test_espresso_espresso_idling_resource_3_0_2_aar.xml b/.idea/libraries/Gradle__com_android_support_test_espresso_espresso_idling_resource_3_0_2_aar.xml
deleted file mode 100644
index 7a77a1025b75ee4844db790997538427920c814b..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_test_espresso_espresso_idling_resource_3_0_2_aar.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_test_monitor_1_0_2_aar.xml b/.idea/libraries/Gradle__com_android_support_test_monitor_1_0_2_aar.xml
deleted file mode 100644
index 18aa7f7ee384314058365a91c338b25f9762ee5a..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_test_monitor_1_0_2_aar.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_test_runner_1_0_2_aar.xml b/.idea/libraries/Gradle__com_android_support_test_runner_1_0_2_aar.xml
deleted file mode 100644
index 22cd55d560438666b9b031255d9bd5c1601c48b2..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_test_runner_1_0_2_aar.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_versionedparcelable_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_versionedparcelable_28_0_0_aar.xml
deleted file mode 100644
index 3a112bc65dcc6c1ad2d884b959a92c7f13848656..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_versionedparcelable_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_android_support_viewpager_28_0_0_aar.xml b/.idea/libraries/Gradle__com_android_support_viewpager_28_0_0_aar.xml
deleted file mode 100644
index 16f4d18fbc97b7d2f96d285fd611f7532ea0e33c..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_android_support_viewpager_28_0_0_aar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml b/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml
deleted file mode 100644
index 5c81a047f1ee385b694a8d66b0c77512402cdca6..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_google_code_gson_gson_1_7_2_jar.xml b/.idea/libraries/Gradle__com_google_code_gson_gson_1_7_2_jar.xml
deleted file mode 100644
index df37096a438d6e11e19b5d7e7de344cf386a7bbb..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_google_code_gson_gson_1_7_2_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1_jar.xml b/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1_jar.xml
deleted file mode 100644
index b5730272ea748bad269085dd9354ed5d5b5fdc26..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__javax_inject_javax_inject_1_jar.xml b/.idea/libraries/Gradle__javax_inject_javax_inject_1_jar.xml
deleted file mode 100644
index 4288a179e8980d40bcaced914a419fd32e8bc9b1..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__javax_inject_javax_inject_1_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__junit_junit_4_12_jar.xml b/.idea/libraries/Gradle__junit_junit_4_12_jar.xml
deleted file mode 100644
index afe704ce650a76b51ef6587f83b5a5083d1bc11e..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__junit_junit_4_12_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__net_sf_kxml_kxml2_2_3_0_jar.xml b/.idea/libraries/Gradle__net_sf_kxml_kxml2_2_3_0_jar.xml
deleted file mode 100644
index b99f612d1cb10aff42bd5a7b6a32ede73fa0e558..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__net_sf_kxml_kxml2_2_3_0_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml
deleted file mode 100644
index 7c8bbe562d35b73abe71d07390b93f3e09ebb3fe..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml
deleted file mode 100644
index 5d03064744abf640ddf6f6ec8cc89b156a4272fd..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml
deleted file mode 100644
index 8f79909d8e696fbbee0a02acd9507a711b2515e6..0000000000000000000000000000000000000000
--- a/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1ddfbbc029bcab630581847471d7f238ec53..0000000000000000000000000000000000000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index 210c0fe3502b4b1fc69bd9d008c85daf8282fa96..0000000000000000000000000000000000000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,871 +0,0 @@
-
-
-
-
-
- android-16
-
-
-
-
-
-
-
-
-
-
- com.android.support
- appcompat-v7
- 28.0.0
- Google,Android Repository
-
-
- org.kie.modules
- com-google-code-gson
- 6.5.0.Final
- JCenter
-
-
- com.android.support.constraint
- constraint-layout
- 2.0.0-beta2
- Google
-
-
- com.android.support.test
- runner
- 1.0.2
- Google,Android Repository
-
-
- com.android.support.test.espresso
- espresso-core
- 3.0.2
- Google,Android Repository
-
-
- 1562080889328
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ThreadStatus
- LOCALAPP_CONFIG
- notKey
- set_uri_edit
- et_uriorjson
- et_undesiredKeyword
- "操作太频繁!"
- getRe
- getAppConfig_Thread
- getLocalAppPackageName_Thread
- pb_progressBar.setVisibility
- sleep
- "无数据!"
- et_uri
- null
- .equals
- if
- ==
- !=
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- C:\Users\John\AppData\Roaming\Subversion
-
-
-
-
- 1557637151288
-
-
- 1557637151288
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..ee5839968a2bf86c93283efc09d40fd050b7cfa2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,127 @@
+ 木兰宽松许可证, 第2版
+
+ 木兰宽松许可证, 第2版
+ 2020年1月 http://license.coscl.org.cn/MulanPSL2
+
+
+ 您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束:
+
+ 0. 定义
+
+ “软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
+
+ “贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
+
+ “贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
+
+ “法人实体”是指提交贡献的机构及其“关联实体”。
+
+ “关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
+
+ 1. 授予版权许可
+
+ 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
+
+ 2. 授予专利许可
+
+ 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
+
+ 3. 无商标许可
+
+ “本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
+
+ 4. 分发限制
+
+ 您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
+
+ 5. 免责声明与责任限制
+
+ “软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
+
+ 6. 语言
+ “本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
+
+ 条款结束
+
+ 如何将木兰宽松许可证,第2版,应用到您的软件
+
+ 如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
+
+ 1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
+
+ 2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
+
+ 3, 请将如下声明文本放入每个源文件的头部注释中。
+
+ Copyright (c) [Year] [name of copyright holder]
+ [Software Name] is licensed under Mulan PSL v2.
+ You can use this software according to the terms and conditions of the Mulan PSL v2.
+ You may obtain a copy of Mulan PSL v2 at:
+ http://license.coscl.org.cn/MulanPSL2
+ THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ See the Mulan PSL v2 for more details.
+
+
+ Mulan Permissive Software License,Version 2
+
+ Mulan Permissive Software License,Version 2 (Mulan PSL v2)
+ January 2020 http://license.coscl.org.cn/MulanPSL2
+
+ Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:
+
+ 0. Definition
+
+ Software means the program and related documents which are licensed under this License and comprise all Contribution(s).
+
+ Contribution means the copyrightable work licensed by a particular Contributor under this License.
+
+ Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
+
+ Legal Entity means the entity making a Contribution and all its Affiliates.
+
+ Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
+
+ 1. Grant of Copyright License
+
+ Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
+
+ 2. Grant of Patent License
+
+ Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
+
+ 3. No Trademark License
+
+ No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4.
+
+ 4. Distribution Restriction
+
+ You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
+
+ 5. Disclaimer of Warranty and Limitation of Liability
+
+ THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ 6. Language
+
+ THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
+
+ END OF THE TERMS AND CONDITIONS
+
+ How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software
+
+ To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:
+
+ i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
+
+ ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;
+
+ iii Attach the statement to the appropriate annotated syntax at the beginning of each source file.
+
+
+ Copyright (c) [Year] [name of copyright holder]
+ [Software Name] is licensed under Mulan PSL v2.
+ You can use this software according to the terms and conditions of the Mulan PSL v2.
+ You may obtain a copy of Mulan PSL v2 at:
+ http://license.coscl.org.cn/MulanPSL2
+ THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ See the Mulan PSL v2 for more details.
diff --git a/app/build.gradle b/app/build.gradle
index 5ae82732d68c0bacba136913eed78d73b0fc727b..826306f070f9505d9721f9fa9489f7a48d6a9d63 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -37,9 +37,10 @@ def static releaseTime() {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
- implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta2'
+ implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.kie.modules:com-google-code-gson:6.5.0.Final'
+ implementation 'com.android.support:design:28.0.0'
}
diff --git a/app/debug/output.json b/app/debug/output.json
new file mode 100644
index 0000000000000000000000000000000000000000..735b64cab3b2d9e392d94e16caf2503ef4cfd08d
--- /dev/null
+++ b/app/debug/output.json
@@ -0,0 +1 @@
+[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"club.lovemo.openapptool-v1.0-1-debug-20190714031109.apk","fullName":"debug","baseName":"debug"},"path":"club.lovemo.openapptool-v1.0-1-debug-20190714031109.apk","properties":{}}]
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index e560306a6afc8d1876ca742747d5395cf34b4b91..303d2a3fe4b5dfd0cdac4f8d98550aeb6c7b61ce 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -41,6 +41,24 @@
#保持泛型
-keepattributes Signature
+#Gson官方混淆配置
+##---------------Begin: proguard configuration for Gson ----------
+# Gson uses generic type information stored in a class file when working with fields. Proguard
+# removes such information by default, so configure it to keep all of it.
+-keepattributes Signature
+
+# For using GSON @Expose annotation
+-keepattributes *Annotation*
+
+# Gson specific classes
+-keep class sun.misc.Unsafe { *; }
+#-keep class com.google.gson.stream.** { *; }
+
+# Application classes that will be serialized/deserialized over Gson
+-keep class club.lovemo.openapptool.entity.AppInfo { *; }
+
+##---------------End: proguard configuration for Gson ----------
+
#保持所有实现 Serializable 接口的类成员
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
@@ -51,6 +69,8 @@
java.lang.Object readResolve();
}
+-keep public class * implements java.io.Serializable {*;}
+
#Fragment不需要在AndroidManifest.xml中注册,需要额外保护下
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment
diff --git a/app/release/output.json b/app/release/output.json
index 5881c41cd1ec90ac09c134c96d39ec6965a375b9..7e1864f468140132bcecc6dac270bc6bf8b8377f 100644
--- a/app/release/output.json
+++ b/app/release/output.json
@@ -1 +1 @@
-[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"club.lovemo.openapptool-v1.0-1-release-20190702151626.apk","fullName":"release","baseName":"release"},"path":"club.lovemo.openapptool-v1.0-1-release-20190702151626.apk","properties":{}}]
\ No newline at end of file
+[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"club.lovemo.openapptool-v1.0-1-release-20190820053503.apk","fullName":"release","baseName":"release"},"path":"club.lovemo.openapptool-v1.0-1-release-20190820053503.apk","properties":{}}]
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index eb7d6b963d0f891ba8a6c8adcf4932183fedce7f..07fa2e3955f7026d72d0f9c079e592a675e24547 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,6 +4,11 @@
package="club.lovemo.openapptool">
+
+
+
+
+
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/club/lovemo/openapptool/activity/MainActivity.java b/app/src/main/java/club/lovemo/openapptool/activity/MainActivity.java
index 38bce15d98f4aa7e3a44eb1f8d56ec6e31c1d14e..9be93012e04480ac10aeebf3d5c9b0d7d78a24d1 100644
--- a/app/src/main/java/club/lovemo/openapptool/activity/MainActivity.java
+++ b/app/src/main/java/club/lovemo/openapptool/activity/MainActivity.java
@@ -1,23 +1,38 @@
package club.lovemo.openapptool.activity;
+import android.Manifest;
import android.annotation.SuppressLint;
+import android.app.DownloadManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.os.Message;
+import android.provider.Settings;
+import android.support.annotation.NonNull;
+import android.support.design.widget.CoordinatorLayout;
+import android.support.design.widget.Snackbar;
+import android.support.v4.content.FileProvider;
+import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
+import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Patterns;
import android.view.Gravity;
@@ -42,6 +57,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
@@ -50,6 +66,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
+import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
@@ -62,12 +79,18 @@ import java.util.List;
import club.lovemo.openapptool.R;
import club.lovemo.openapptool.entity.AppInfo;
+import club.lovemo.openapptool.permission.PermissionListener;
+import club.lovemo.openapptool.permission.PermissionManager;
+import club.lovemo.openapptool.utils.DownloadService;
import club.lovemo.openapptool.utils.SharedPreferencesUtils;
+import club.lovemo.openapptool.utils.StringAdapter;
+import club.lovemo.openapptool.utils.UriAdapter;
import club.lovemo.openapptool.utils.Utils;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private List mainAppInfoList = new ArrayList<>();
private MyAdapter adapter;
+ private CoordinatorLayout container;
//private TextView tv_show_category;
ListView packageListView;
private AlertDialog dialog;
@@ -89,7 +112,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private static final int LOCAL_APP_CONFIG = 0;//使用本地应用
private static final int NETWORK_CONFIG = 1;//使用网络配置
private static final int LOCAL_CONFIG = 2;//使用本地配置
- private static final String LogTag = "MyLogTag";
+ public static final String LogTag = "MyLogTag";
private static String undesiredKeyword = "com.android";
public static boolean NetworkThreadStatus = false;//网络请求线程状态
public static boolean GetPackageNameThreadStatus = false;//获取本地包名线程状态
@@ -127,7 +150,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
Toast.makeText(activity, activity.getString(R.string.text_CurrentUseLocalCache), Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
- Utils.print(LogTag, e.getMessage());
+ e.printStackTrace();
+ Toast.makeText(activity,e.getMessage(),Toast.LENGTH_LONG).show();
}
break;
case GET_PACKAGE_NAME_SUCCESS:
@@ -166,6 +190,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
et_search = findViewById(R.id.main_search);
main_spinner = findViewById(R.id.main_spinner);
main_loading_relative = findViewById(R.id.main_loading_relative);
+ container = findViewById(R.id.container);
main_loading_relative.bringToFront();
//设置toolbar
main_toolbar.setTitle(R.string.app_name);
@@ -174,7 +199,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
//设置hint字体
et_UriOrJson.setTypeface(Typeface.DEFAULT);
sharedPreferencesUtils = new SharedPreferencesUtils(MainActivity.this);
+ //Permission_to_request();
Init();
+ register();
main_loading_relative.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -225,13 +252,16 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
break;
case LOCAL_CONFIG:
String local_config = sharedPreferencesUtils.getLocalConfig();
- if (0 != local_config.length()) {
+ if (0 < local_config.length()) {
try {
mainAppInfoList = formatJson(local_config);
Search();
} catch (Exception e) {
- Utils.showToast(MainActivity.this,getString(R.string.text_NOData));
+ e.printStackTrace();
+ Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
+ }else {
+ Utils.showToast(MainActivity.this,getString(R.string.text_NOData));
}
break;
}
@@ -275,6 +305,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
});
+ //设置radioGroup点击事件
settingRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
@@ -285,19 +316,32 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
// 获取这个RadioButton的text内容
//String output = choice.getText().toString();
//Utils.print(LogTag,"你选择的是:" + output);
+
+ String tempStr = "";
if (settingRadioBtnLocalApp.isChecked()){
+ if (0 == undesiredKeyword.length()){
+ et_UndesiredKeyword.setText(getString(R.string.text_ComAndroid));
+ et_UndesiredKeyword.setSelection(getString(R.string.text_ComAndroid).length());
+ }else {
+ et_UndesiredKeyword.setText(undesiredKeyword);
+ et_UndesiredKeyword.setSelection(undesiredKeyword.length());
+ }
et_UndesiredKeyword.setVisibility(View.VISIBLE);
et_UriOrJson.setVisibility(View.GONE);
}else if (settingRadioBtnNetwork.isChecked()){
+ tempStr = sharedPreferencesUtils.getUri();
et_UndesiredKeyword.setVisibility(View.GONE);
et_UriOrJson.setVisibility(View.VISIBLE);
}else if(settingRadioBtnLocal.isChecked()){
+ tempStr = sharedPreferencesUtils.getLocalConfig();
et_UndesiredKeyword.setVisibility(View.GONE);
et_UriOrJson.setVisibility(View.VISIBLE);
}
+ et_UriOrJson.setText(tempStr);
+ //设置光标至末尾
+ et_UriOrJson.setSelection(tempStr.length());
}
});
-
}
/**
@@ -352,6 +396,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
customAppNameMap.put(key,value);
}
}catch (JSONException jsonE){
+ jsonE.printStackTrace();
Utils.print(LogTag,getString(R.string.text_InitCustomAppNameConfigError)+jsonE.getMessage());
Utils.showToast(MainActivity.this,getString(R.string.text_InitCustomAppNameConfigError));
}
@@ -384,6 +429,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
mainAppInfoList = formatJson(local_config);
Search();
} catch (Exception e) {
+ e.printStackTrace();
+ Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_LONG).show();
Dialog();
}
}
@@ -413,11 +460,22 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
break;
case R.id.ll_item3:
MainActivity.this.finish();
+ MainActivity.this.overridePendingTransition(R.anim.zoom_enter,R.anim.zoom_exit);
break;
case R.id.openBtn:
//获取点击的item index 后打开App
int position = (Integer) view.getTag();
- openApp(adapter.appInfoList.get(position).getAppPackage());
+ AppInfo appInfo = adapter.appInfoList.get(position);
+ if(!checkPackInfo(appInfo.getAppPackage()) && appInfo.getDownloadUri() != null ){
+ if(!isMarshmallow()){
+ Permission_to_request(appInfo);
+ }else {
+ Utils.showToast(MainActivity.this,appInfo.getAppName()+":已添加到下载队列");
+ download(appInfo);
+ }
+ }else {
+ openApp(appInfo.getAppPackage());
+ }
break;
}
//点击PopWindow的item后,关闭此PopWindow
@@ -539,13 +597,17 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
break;
case LOCAL_CONFIG:
String localConfig = sharedPreferencesUtils.getLocalConfig();
- if (0 < localConfig.length())
+ if (0 < localConfig.length()){
try {
mainAppInfoList = formatJson(localConfig);
Search();
} catch (Exception e) {
- Utils.showToast(MainActivity.this,getString(R.string.text_LocalDataError));
+ e.printStackTrace();
+ Toast.makeText(MainActivity.this,getString(R.string.text_LocalDataError)+"\nErrorMsg:"+e.getMessage(),Toast.LENGTH_LONG).show();
}
+ }else {
+ Utils.showToast(MainActivity.this,getString(R.string.text_LocalDataError));
+ }
break;
}
dialog.cancel();
@@ -581,7 +643,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
dialog.cancel();
} catch (Exception e) {
- Utils.showToast(MainActivity.this, getString(R.string.text_NotUrlOrJson));
+ e.printStackTrace();
+ Toast.makeText(MainActivity.this,getString(R.string.text_NotUrlOrJson) +"\nErrorMsg:"+e.getMessage(),Toast.LENGTH_LONG).show();
}
}
} else {
@@ -599,7 +662,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
}
});
-
String tempStr = "";
if (settingRadioBtnLocalApp.isChecked()){
et_UndesiredKeyword.setVisibility(View.VISIBLE);
@@ -658,12 +720,16 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
* @param packageName 包名
*/
public void toAppSettingByPackageName(Context context, String packageName) {
- Intent mIntent = new Intent();
- mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
- mIntent.setData(Uri.fromParts("package", packageName, null));
- context.startActivity(mIntent);
- this.overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left);
+ if (checkPackInfo(packageName)){
+ Intent mIntent = new Intent();
+ mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
+ mIntent.setData(Uri.fromParts("package", packageName, null));
+ context.startActivity(mIntent);
+ this.overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left);
+ }else {
+ Utils.showToast(MainActivity.this,getString(R.string.text_ApplicationNotInstalled));
+ }
}
/**
@@ -735,12 +801,15 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
mHandler.sendEmptyMessage(GET_ERROR);
}
} catch (Exception e) {
+ e.printStackTrace();
Utils.print(LogTag, "获取数据异常:" + e.getMessage());
+ //Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_LONG ).show();
mHandler.sendEmptyMessage(GET_ERROR);
}
}
}.start();
}
+
/**
* 获取手机上所有应用的包名和APPName,排除关键字
* @param undesiredKeyword 排除关键字
@@ -767,7 +836,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
appInfo.setAppPackage(packageName);
appInfo.setId(appInfoList.size() + 1);
appInfoList.add(appInfo);
-// Utils.print(LogTag, "getAppProcessName: " + packageName + "-----Name:" + name);
}
}
mainAppInfoList = appInfoList;
@@ -804,18 +872,25 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
JsonParser parser = new JsonParser();
//将JSON的String 转成一个JsonArray对象
JsonArray jsonArray = parser.parse(str).getAsJsonArray();
- Gson gson = new Gson();
+ GsonBuilder gsonBuilder = new GsonBuilder();
+ //注册适配器
+ gsonBuilder.registerTypeAdapter(Uri.class,new UriAdapter(this)).registerTypeAdapter(String.class,new StringAdapter(this)).setPrettyPrinting();
+ Gson gson = gsonBuilder.create();
+
List appInfoList = new ArrayList<>();
//加强for循环遍历JsonArray
for (JsonElement json : jsonArray) {
//使用GSON,直接转成Bean对象
+ Utils.print(LogTag,json.toString()+"Json格式化");
AppInfo appInfo = gson.fromJson(json, AppInfo.class);
- //Utils.print(LogTag,appInfo.toString()+"Json格式化");
+ Utils.print(LogTag,"AppInfo:"+appInfo.toString());
appInfoList.add(appInfo);
}
return appInfoList;
}
+
+
/**
* 保存用户设置的自定义包名配置
*/
@@ -915,13 +990,21 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
holder.tv_app_name.setText(appInfo.getAppName());
holder.tv_app_package.setText(appInfo.getAppPackage());
if (checkPackInfo(appInfo.getAppPackage())) {
+ holder.btn_open_app.setText(R.string.text_Open);
holder.tv_app_install.setVisibility(View.GONE);
holder.btn_open_app.setVisibility(View.VISIBLE);
} else {
- holder.btn_open_app.setVisibility(View.GONE);
- holder.tv_app_install.setVisibility(View.VISIBLE);
- holder.tv_app_install.setText(R.string.text_Uninstalled);
- holder.tv_app_install.setTextColor(getResources().getColor(R.color.menu));
+ if (appInfo.getDownloadUri() != null)
+ {
+ holder.tv_app_install.setVisibility(View.GONE);
+ holder.btn_open_app.setVisibility(View.VISIBLE);
+ holder.btn_open_app.setText(R.string.text_Download);
+ }else {
+ holder.btn_open_app.setVisibility(View.GONE);
+ holder.tv_app_install.setVisibility(View.VISIBLE);
+ holder.tv_app_install.setText(R.string.text_Uninstalled);
+ holder.tv_app_install.setTextColor(getResources().getColor(R.color.menu));
+ }
}
return convertView;
}
@@ -935,6 +1018,217 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private Button btn_open_app;
}
+ private PermissionManager helper;
+ private static final int REQUEST_CODE_CAMERA=1;
+
+ /**
+ * 动态权限获取
+ */
+ private void Permission_to_request(final AppInfo appInfo){
+ helper = PermissionManager.with(MainActivity.this)
+ //添加权限请求码
+ .addRequestCode(MainActivity.REQUEST_CODE_CAMERA)
+ //设置权限,可以添加多个权限
+ .permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)
+ //设置权限监听器
+ .setPermissionsListener(new PermissionListener() {
+
+ @Override
+ public void onGranted() {
+ //当权限被授予时调用
+ Utils.showToast(MainActivity.this,"获取权限成功");
+ //MyThread();
+ //download(appInfo.getDownloadUrl());
+ download(appInfo);
+ }
+
+ @Override
+ public void onDenied() {
+ //用户拒绝该权限时调用
+ Utils.showToast(MainActivity.this,"权限被拒绝");
+ openSettingActivity(MainActivity.this,getResources().getString(R.string.text_open_the_necessary_permissions));
+ }
+
+ @Override
+ public void onShowRationale(String[] permissions) {
+ //当用户拒绝某权限时并点击`不再提醒`的按钮时,下次应用再请求该权限时,需要给出合适的响应(比如,给个展示对话框来解释应用为什么需要该权限)
+ Snackbar.make(container, R.string.text_need_to_access, Snackbar.LENGTH_INDEFINITE)
+ .setAction(R.string.text_Ok, new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ //必须调用该`setIsPositive(true)`方法
+ helper.setIsPositive(true);
+ helper.request();
+ }
+ }).show();
+ }
+ })
+ //请求权限
+ .request();
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ switch (requestCode) {
+ case REQUEST_CODE_CAMERA:
+ helper.onPermissionResult(permissions, grantResults);
+ break;
+ }
+ }
+
+ private boolean isMarshmallow() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
+ }
+
+ private void showMessageOKCancel(final MainActivity context, String message, DialogInterface.OnClickListener okListener) {
+ new AlertDialog.Builder(context)
+ .setMessage(message)
+ .setPositiveButton(R.string.text_Ok, okListener)
+ .setNegativeButton(R.string.text_Close, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ Utils.showToast(MainActivity.this,"权限被拒绝,无法下载!");
+ //MainActivity.this.finish();
+ }
+ }).create().show();
+
+ }
+
+ private void openSettingActivity(final MainActivity activity, String message) {
+ showMessageOKCancel(activity, message, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
+ intent.setData(uri);
+ activity.startActivity(intent);
+ //MainActivity.this.finish();
+ }
+ });
+ }
+
+ protected MyReceiver receiver = new MyReceiver();
+
+ /**
+ * 注册广播的方法(动态注册)
+ */
+ private void register() {
+ IntentFilter intentFilter = new IntentFilter(DownloadService.BROADCAST_ACTION);
+ intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
+ LocalBroadcastManager.getInstance(this).registerReceiver(receiver, intentFilter);
+ }
+
+ /**
+ * 下载方法
+ * @param appInfo appInfo
+ */
+ public void download(AppInfo appInfo){
+ String downloadFileName = Utils.MD5Encoder(appInfo.getDownloadUri().toString())+".apk";
+ File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/" +downloadFileName);
+ if (!file.exists()) {
+ Intent myServiceIntent = new Intent(MainActivity.this, DownloadService.class);
+ myServiceIntent.setData(appInfo.getDownloadUri());
+ myServiceIntent.putExtra(DownloadService.DOWNLOAD_TITLE,appInfo.getAppName());
+ myServiceIntent.putExtra(DownloadService.DOWNLOAD_FILE_NAME,downloadFileName);
+ startService(myServiceIntent);
+ }else {
+ Toast.makeText(this,"检查到本地已经存在特征相同文件,调起安装",Toast.LENGTH_LONG).show();
+ installApk(MainActivity.this,Environment.DIRECTORY_DOWNLOADS + "/" +downloadFileName);
+ }
+ }
+
+ /**
+ * 接收下载信息广播,下载完成,自动安装应用
+ */
+ private class MyReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ //String data = intent.getStringExtra(DownloadService.EXTENDED_DATA_STATUS);
+ int status = intent.getIntExtra(DownloadService.EXTENDED_DATA_STATUS, -1);
+ String downloadFileName;
+ String downloadTitle;
+ switch (status){
+ case DownloadManager.STATUS_SUCCESSFUL:
+ //long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
+ downloadFileName = intent.getStringExtra(DownloadService.DOWNLOAD_FILE_NAME);
+ downloadTitle = intent.getStringExtra(DownloadService.DOWNLOAD_TITLE);
+ Toast.makeText(MainActivity.this, downloadTitle+"下载已经完成!",Toast.LENGTH_LONG).show();
+ installApk(MainActivity.this,Environment.DIRECTORY_DOWNLOADS + "/"+downloadFileName);
+ break;
+ case DownloadManager.STATUS_FAILED:
+ //long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
+ String uri = intent.getStringExtra(DownloadService.DOWNLOAD_URI);
+ downloadTitle = intent.getStringExtra(DownloadService.DOWNLOAD_TITLE);
+ Toast.makeText(MainActivity.this,downloadTitle+"下载失败,将调起浏览器进行下载!",Toast.LENGTH_LONG).show();
+ try {//携带下载链接跳转到浏览器
+ if (!TextUtils.isEmpty(uri) && uri.startsWith("https://")) {
+ intent.setAction(Intent.ACTION_VIEW);
+ Uri content_url = Uri.parse(uri);
+ intent.setData(content_url);
+ MainActivity.this.startActivity(intent);
+ }else {
+ Toast.makeText(MainActivity.this,getString(R.string.text_NotHTTPSAddresses),Toast.LENGTH_LONG).show();
+ }
+ } catch (Exception e) {
+ //异常处理
+ e.printStackTrace();
+ }
+ break;
+ case DownloadManager.STATUS_PAUSED:
+ downloadTitle = intent.getStringExtra(DownloadService.DOWNLOAD_TITLE);
+ Toast.makeText(MainActivity.this,getString(R.string.text_DownloadPaused)+downloadTitle,Toast.LENGTH_LONG).show();
+ break;
+ case DownloadManager.STATUS_PENDING:
+ downloadTitle = intent.getStringExtra(DownloadService.DOWNLOAD_TITLE);
+ Toast.makeText(MainActivity.this,getString(R.string.text_DownloadPending)+downloadTitle,Toast.LENGTH_LONG).show();
+ break;
+ default:
+ }
+ boolean startDownStatus = intent.getBooleanExtra(DownloadService.DOWNLOAD_START_STATUS,true);
+ if (!startDownStatus){
+ Utils.showToast(MainActivity.this,getString(R.string.text_StartDownloadFailed));
+ }
+ }
+ }
+
+ /**
+ * 调起apk安装操作
+ * @param context Context
+ * @param filePath apk路径
+ */
+ private void installApk(Context context,String filePath){
+ Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
+ Utils.print(LogTag,"文件地址:"+filePath);
+ File apkFile = getExternalFilesDir(filePath);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
+ // 声明需要的临时的权限
+ intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ if (apkFile != null){
+ Uri uriForFile = FileProvider.getUriForFile(context, "club.lovemo.openapptool.fileprovider", apkFile);
+ intent.setDataAndType(uriForFile,"application/vnd.android.package-archive");
+ }else {
+ Utils.print(LogTag,"apkFile为空!");
+ return;
+ }
+ }else {
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
+ }
+ //intent.setDataAndType(Uri.fromFile(new File(Environment.DIRECTORY_DOWNLOADS + "/" +downloadFileName)), "application/vnd.android.package-archive");
+ context.startActivity(intent);
+ }
+
+ /**
+ * 销毁时取消注册广播
+ */
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
+ }
+
@Override
protected void onStop() {
super.onStop();
@@ -945,6 +1239,10 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
@Override
public void onResume() {
super.onResume();
+ //如果当前应用不为竖屏则设置为竖屏
+ if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_PORTRAIT){
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ }
//防止应用切换到前台时自动弹出输入框
et_search.clearFocus();
}
diff --git a/app/src/main/java/club/lovemo/openapptool/entity/AppInfo.java b/app/src/main/java/club/lovemo/openapptool/entity/AppInfo.java
index fde44624bc34565875f4ab1aaf5af3a5e19ff008..25e3fcdfc7b081dcf76cbd10c86044b202df45ea 100644
--- a/app/src/main/java/club/lovemo/openapptool/entity/AppInfo.java
+++ b/app/src/main/java/club/lovemo/openapptool/entity/AppInfo.java
@@ -1,5 +1,7 @@
package club.lovemo.openapptool.entity;
+import android.net.Uri;
+
public class AppInfo {
public Integer getId() {
return id;
@@ -29,16 +31,32 @@ public class AppInfo {
private String appName;
private String appPackage;
- public AppInfo(Integer id, String appName, String appPackage) {
+ public Uri getDownloadUri() {
+ return downloadUri;
+ }
+
+ public void setDownloadUri(Uri downloadUri) {
+ this.downloadUri = downloadUri;
+ }
+
+ private Uri downloadUri;
+
+ public AppInfo(Integer id, String appName, String appPackage,Uri downloadUri) {
this.id = id;
this.appName = appName;
this.appPackage = appPackage;
+ this.downloadUri = downloadUri;
}
- public AppInfo() {
- }
+ public AppInfo() { }
+ @Override
public String toString() {
- return appName + '\n' + appPackage;
+ return "AppInfo{" +
+ "id=" + id +
+ ", appName='" + appName + '\'' +
+ ", appPackage='" + appPackage + '\'' +
+ ", downloadUrl=" + downloadUri +
+ '}';
}
}
diff --git a/app/src/main/java/club/lovemo/openapptool/permission/PermissionListener.java b/app/src/main/java/club/lovemo/openapptool/permission/PermissionListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..c6c79d28ab74bb64e1a7c27706a578aff5d3f8e2
--- /dev/null
+++ b/app/src/main/java/club/lovemo/openapptool/permission/PermissionListener.java
@@ -0,0 +1,24 @@
+package club.lovemo.openapptool.permission;
+
+/**权限监听器
+ * @class PermissionListener
+ * @author xzb
+ */
+public interface PermissionListener {
+ /**
+ * 用户授权后调用
+ */
+ void onGranted();
+
+ /**
+ * 用户禁止后调用
+ */
+ void onDenied();
+
+ /**是否显示阐述性说明
+ * @param permissions 返回需要显示说明的权限数组
+ */
+ void onShowRationale(String[] permissions);
+}
+
+
diff --git a/app/src/main/java/club/lovemo/openapptool/permission/PermissionManager.java b/app/src/main/java/club/lovemo/openapptool/permission/PermissionManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..dbff6214b78f2c9f46fe13f4c8728894894c15f0
--- /dev/null
+++ b/app/src/main/java/club/lovemo/openapptool/permission/PermissionManager.java
@@ -0,0 +1,155 @@
+package club.lovemo.openapptool.permission;
+
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.app.Fragment;
+import android.support.v4.content.ContextCompat;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 权限管理
+ * @author xzb
+ * @class PermissionManager
+ */
+public class PermissionManager {
+
+ private Object mObject;
+ private String[] mPermissions;
+ private int mRequestCode;
+ private PermissionListener mListener;
+ // 用户是否确认了解释框的
+ private boolean mIsPositive = false;
+
+ public static PermissionManager with(Activity activity) {
+ return new PermissionManager(activity);
+ }
+
+ public static PermissionManager with(Fragment fragment) {
+ return new PermissionManager(fragment);
+ }
+
+ public PermissionManager permissions(String... permissions) {
+ this.mPermissions = permissions;
+ return this;
+ }
+
+ public PermissionManager addRequestCode(int requestCode) {
+ this.mRequestCode = requestCode;
+ return this;
+ }
+
+ public PermissionManager setPermissionsListener(PermissionListener listener) {
+ this.mListener = listener;
+ return this;
+ }
+
+ public PermissionManager(Object object) {
+ this.mObject = object;
+ }
+
+ /**请求权限
+ * @return PermissionManager
+ */
+ public PermissionManager request() {
+ request(mObject, mPermissions, mRequestCode);
+ return this;
+ }
+
+ private void request(Object object, String[] permissions, int requestCode) {
+ // 根据权限集合去查找是否已经授权过
+ Map> map = findDeniedPermissions(getActivity(object), permissions);
+ List deniedPermissions = map.get("deny");
+ List rationales = map.get("rationale");
+ if (deniedPermissions != null && deniedPermissions.size() > 0) {
+ // 第一次点击deny才调用,mIsPositive是为了防止点确认解释框后调request()递归调onShowRationale
+ if (rationales != null && rationales.size() > 0 && !mIsPositive) {
+ if (mListener != null ) {
+ mListener.onShowRationale(rationales.toArray(new String[rationales.size()]));
+ }
+ return;
+ }
+ if (object instanceof Activity) {
+ ActivityCompat.requestPermissions((Activity) object, deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
+ } else if (object instanceof Fragment) {
+ ((Fragment) object).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
+ } else {
+ throw new IllegalArgumentException(object.getClass().getName() + " is not supported");
+ }
+ } else {
+ if (mListener != null) {
+ mListener.onGranted();
+ }
+ }
+ }
+
+ /**根据requestCode处理响应的权限
+ * @param permissions
+ * @param results
+ */
+ public void onPermissionResult(String[] permissions, int[] results) {
+ List deniedPermissions = new ArrayList();
+ for (int i = 0; i < results.length; i++) {
+ if (results[i] != PackageManager.PERMISSION_GRANTED) {//未授权
+ deniedPermissions.add(permissions[i]);
+ }
+ }
+ if (deniedPermissions.size() > 0) {
+ if (mListener != null) {
+ mListener.onDenied();
+ }
+ } else {
+ if (mListener != null) {
+ mListener.onGranted();
+ }
+ }
+ }
+
+ private Map> findDeniedPermissions(Activity activity, String... permissions) {
+ Map> map = new HashMap>();
+ List denyList = new ArrayList();//未授权的权限
+ List rationaleList = new ArrayList();//需要显示提示框的权限
+ for (String value : permissions) {
+ if (ContextCompat.checkSelfPermission(activity, value) != PackageManager.PERMISSION_GRANTED) {
+ denyList.add(value);
+ if (shouldShowRequestPermissionRationale(value)) {
+ rationaleList.add(value);
+ }
+ }
+ }
+ map.put("deny", denyList);
+ map.put("rationale", rationaleList);
+ return map;
+ }
+
+ private Activity getActivity(Object object) {
+ if (object instanceof Fragment) {
+ return ((Fragment) object).getActivity();
+ } else if (object instanceof Activity) {
+ return (Activity) object;
+ }
+ return null;
+ }
+
+ /**
+ * 当用户拒绝某权限时并点击就不再提醒的按钮时,下次应用再请求该权限时,需要给出合适的响应(比如给个展示对话框)
+ * @param permission
+ */
+ private boolean shouldShowRequestPermissionRationale(String permission) {
+ if (mObject instanceof Activity) {
+ return ActivityCompat.shouldShowRequestPermissionRationale((Activity) mObject, permission);
+ } else if (mObject instanceof Fragment) {
+ return ((Fragment) mObject).shouldShowRequestPermissionRationale(permission);
+ } else {
+ throw new IllegalArgumentException(mObject.getClass().getName() + " is not supported");
+ }
+ }
+
+ public void setIsPositive(boolean isPositive) {
+ this.mIsPositive = isPositive;
+ }
+}
diff --git a/app/src/main/java/club/lovemo/openapptool/utils/DownloadService.java b/app/src/main/java/club/lovemo/openapptool/utils/DownloadService.java
new file mode 100644
index 0000000000000000000000000000000000000000..785426342134c7acde62ad9298e5345aa32fe98b
--- /dev/null
+++ b/app/src/main/java/club/lovemo/openapptool/utils/DownloadService.java
@@ -0,0 +1,119 @@
+package club.lovemo.openapptool.utils;
+
+import android.app.DownloadManager;
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Environment;
+import android.support.v4.content.LocalBroadcastManager;
+
+public class DownloadService extends IntentService {
+ public static final String BROADCAST_ACTION = "club.lovemo.openapptool.DownloadService";
+ public static final String EXTENDED_DATA_STATUS = "club.lovemo.openapptool.DownloadService.STATUS";
+ public static final String DOWNLOAD_START_STATUS = "club.lovemo.openapptool.DownloadStart.STATUS";
+ public static final String DOWNLOAD_URI = "club.lovemo.openapptool.Download.Uri";
+ public static final String DOWNLOAD_TITLE = "DOWNLOAD_TITLE";
+ public static final String DOWNLOAD_FILE_NAME = "DOWNLOAD_FILE_NAME";
+
+ public DownloadService() {
+ super("DownloadService");
+ }
+
+ @Override
+ protected void onHandleIntent (Intent intent) {
+ //获取下载地址
+ Uri uri = intent.getData();
+ String TAG = "DownloadService";
+ Utils.print(TAG,uri + ":uri");
+ //获取DownloadManager对象
+ DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
+ DownloadManager.Request request;
+ Intent localIntent = new Intent(BROADCAST_ACTION);
+ try {
+ request = new DownloadManager.Request(uri);
+ }catch (Exception e){
+ e.printStackTrace();
+ localIntent.putExtra(DOWNLOAD_START_STATUS,false);
+ LocalBroadcastManager mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
+ mLocalBroadcastManager.sendBroadcast(localIntent);
+ return;
+ }
+ String downloadTitle = intent.getStringExtra(DOWNLOAD_TITLE);
+ String downloadFileName = intent.getStringExtra(DOWNLOAD_FILE_NAME);
+ //指定APK缓存路径和应用名称,可在SD卡/Android/data/包名/file/Download文件夹中查看
+ request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, downloadFileName);
+ //设置网络下载环境为wifi
+ request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
+ //设置显示通知栏,下载完成后通知栏自动消失
+ request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE | DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+ //设置通知栏标题
+ request.setTitle(downloadFileName);
+ request.setDescription(uri.toString());
+ request.setAllowedOverRoaming(false);
+
+ //获得唯一下载id
+ assert downloadManager != null;
+ long requestId = downloadManager.enqueue(request);
+ //查询下载信息
+ DownloadManager.Query query=new DownloadManager.Query();
+ query.setFilterById(requestId);
+ try{
+ boolean isEnd=false;
+ //调用LocalBroadcastManager.sendBroadcast将intent传递回去
+ LocalBroadcastManager mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
+ while(!isEnd){
+ Cursor cursor = downloadManager.query(query);
+ if (cursor != null && cursor.moveToFirst()) {
+ int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
+ switch(status){
+ //如果下载状态为成功
+ case DownloadManager.STATUS_SUCCESSFUL:
+ Utils.print(TAG,"下载成功!STATUS_SUCCESSFUL status:"+ status);
+ isEnd=true;
+ //将id放进Intent
+ localIntent.putExtra(EXTENDED_DATA_STATUS,status);
+ localIntent.putExtra(DOWNLOAD_FILE_NAME,downloadFileName);
+ localIntent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID,requestId);
+ localIntent.putExtra(DownloadService.DOWNLOAD_TITLE,downloadTitle);
+ mLocalBroadcastManager.sendBroadcast(localIntent);
+ break;
+ case DownloadManager.STATUS_RUNNING:
+ Utils.print(TAG,"下载中!STATUS_RUNNING status:"+ status);
+ break;
+ case DownloadManager.STATUS_FAILED:
+ isEnd = true;
+ Utils.print(TAG,"下载失败!STATUS_FAILED status:"+ status);
+ localIntent.putExtra(EXTENDED_DATA_STATUS,status);
+ localIntent.putExtra(DOWNLOAD_URI,uri.toString());
+ localIntent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID,requestId);
+ localIntent.putExtra(DownloadService.DOWNLOAD_TITLE,downloadTitle);
+ mLocalBroadcastManager.sendBroadcast(localIntent);
+ break;
+ case DownloadManager.STATUS_PAUSED:
+ Utils.print(TAG,"下载暂停!STATUS_PAUSED status:"+ status);
+ localIntent.putExtra(EXTENDED_DATA_STATUS,status);
+ localIntent.putExtra(DownloadService.DOWNLOAD_TITLE,downloadTitle);
+ mLocalBroadcastManager.sendBroadcast(localIntent);
+ break;
+ case DownloadManager.STATUS_PENDING:
+ Utils.print(TAG,"等待下载!STATUS_PENDING status:"+ status);
+ localIntent.putExtra(EXTENDED_DATA_STATUS,status);
+ localIntent.putExtra(DownloadService.DOWNLOAD_TITLE,downloadTitle);
+ mLocalBroadcastManager.sendBroadcast(localIntent);
+ break;
+ default:
+ isEnd=true;
+ Utils.print(TAG,"未知下载状态!status:"+ status);
+ }
+ }
+ if(cursor!=null){
+ cursor.close();
+ }
+ }
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/app/src/main/java/club/lovemo/openapptool/utils/StringAdapter.java b/app/src/main/java/club/lovemo/openapptool/utils/StringAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..3da0cc0995950e71c7b485606b42ac0e8ad292d9
--- /dev/null
+++ b/app/src/main/java/club/lovemo/openapptool/utils/StringAdapter.java
@@ -0,0 +1,63 @@
+package club.lovemo.openapptool.utils;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonPrimitive;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+
+import java.lang.reflect.Type;
+
+import club.lovemo.openapptool.R;
+
+
+/**
+ * Json String类型解析自定义适配器
+ */
+public class StringAdapter implements JsonSerializer, JsonDeserializer {
+
+ private Context ctx;
+
+ public StringAdapter(Context ctx){
+ this.ctx = ctx;
+ }
+
+ /**
+ * 反序列化
+ * @param json json
+ * @param typeOfT typeOfT
+ * @param context context
+ * @return String
+ * @throws JsonParseException not String
+ */
+ @Override
+ public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+ if(json == null || json.getAsString().trim().length() == 0){
+ Resources res = ctx.getResources();
+ throw new JsonParseException(res.getString(R.string.text_StringNotEmpty));
+ } else {
+ return json.getAsString();
+ }
+ }
+
+ /**
+ * 序列化
+ * @param src String
+ * @param typeOfSrc typeOfSrc
+ * @param context context
+ * @return JsonElement
+ */
+ @Override
+ public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
+ String value = "";
+ if(src != null){
+ value = src;
+ }
+ return new JsonPrimitive(value);
+ }
+}
diff --git a/app/src/main/java/club/lovemo/openapptool/utils/UriAdapter.java b/app/src/main/java/club/lovemo/openapptool/utils/UriAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..437f6d86b04bbcead221cf743cab8b6cc9aba322
--- /dev/null
+++ b/app/src/main/java/club/lovemo/openapptool/utils/UriAdapter.java
@@ -0,0 +1,75 @@
+package club.lovemo.openapptool.utils;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.util.Patterns;
+
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonPrimitive;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+
+import java.lang.reflect.Type;
+
+import club.lovemo.openapptool.R;
+
+
+/**
+ * Json Uri类型解析自定义适配器
+ */
+public class UriAdapter implements JsonSerializer, JsonDeserializer {
+
+ private Context ctx;
+
+ public UriAdapter(Context ctx){
+ this.ctx = ctx;
+ }
+
+ /**
+ * 反序列化
+ * @param json json
+ * @param typeOfT typeOfT
+ * @param context context
+ * @return Uri
+ * @throws JsonParseException not Url
+ */
+ @Override
+ public Uri deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+ if(json == null || json.getAsString().trim().length() == 0){
+ return null;
+ } else {
+ String str = json.getAsString().trim();
+ if (Patterns.WEB_URL.matcher(str).matches()){
+ if (str.startsWith("https://")){
+ return Uri.parse(json.getAsString());
+ }else {
+ Resources res = ctx.getResources();
+ throw new JsonParseException(res.getString(R.string.text_NotHTTPSAddresses));
+ }
+ }else {
+ Resources res = ctx.getResources();
+ throw new JsonParseException(res.getString(R.string.text_DownloadAddressError));
+ }
+ }
+ }
+
+ /**
+ * 序列化
+ * @param src Uri
+ * @param typeOfSrc typeOfSrc
+ * @param context context
+ * @return JsonElement
+ */
+ @Override
+ public JsonElement serialize(Uri src, Type typeOfSrc, JsonSerializationContext context) {
+ String value = "";
+ if(src != null){
+ value = src.toString();
+ }
+ return new JsonPrimitive(value);
+ }
+}
diff --git a/app/src/main/java/club/lovemo/openapptool/utils/Utils.java b/app/src/main/java/club/lovemo/openapptool/utils/Utils.java
index 5761e65710ec2cc3354dde618536f69a3966d7c0..00ed8cc7b8506da6b750d26a0b6067b151dc1be0 100644
--- a/app/src/main/java/club/lovemo/openapptool/utils/Utils.java
+++ b/app/src/main/java/club/lovemo/openapptool/utils/Utils.java
@@ -132,11 +132,11 @@ public class Utils {
}
return str;
}catch (Exception e){
+ return null;
}
- return null;
}
- public static String encode(String string) throws Exception {
+ private static String encode(String string) throws Exception {
byte[] hash = MessageDigest.getInstance("MD5").digest(
string.getBytes(Charset.forName("UTF-8")));
StringBuilder hex = new StringBuilder(hash.length * 2);
@@ -180,11 +180,10 @@ public class Utils {
} catch (Exception e) {
e.printStackTrace();
}
-
return pi;
}
- public static String savePhoto(Bitmap photoBitmap, String path,
- String photoName) {
+
+ public static String savePhoto(Bitmap photoBitmap, String path, String photoName) {
String localPath = null;
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED)) {
@@ -192,7 +191,6 @@ public class Utils {
if (!dir.exists()) {
dir.mkdirs();
}
-
File photoFile = new File(path, photoName + ".png");
FileOutputStream fileOutputStream = null;
try {
@@ -262,31 +260,22 @@ public class Utils {
dst_right = height;
dst_bottom = height;
}
-
Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
-
final int color = 0xff424242;
final Paint paint = new Paint();
- final Rect src = new Rect((int) left, (int) top, (int) right,
- (int) bottom);
- final Rect dst = new Rect((int) dst_left, (int) dst_top,
- (int) dst_right, (int) dst_bottom);
+ final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom);
+ final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);
final RectF rectF = new RectF(dst);
-
paint.setAntiAlias(true);// 设置画笔无锯齿
-
canvas.drawARGB(0, 0, 0, 0); // 填充整个Canvas
paint.setColor(color);
-
// 以下有两种方法画圆,drawRounRect和drawCircle
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);//
// 画圆角矩形,第一个参数为图形显示区域,第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。
canvas.drawCircle(roundPx, roundPx, roundPx, paint);
-
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));// 设置两张图片相交时的模式,参考http://trylovecatch.iteye.com/blog/1189452
canvas.drawBitmap(bitmap, src, dst, paint); // 以Mode.SRC_IN模式合并bitmap和已经draw了的Circle
-
return output;
}
}
diff --git a/app/src/main/res/layout/action_overflow_popwindow.xml b/app/src/main/res/layout/action_overflow_popwindow.xml
index 297867aa9e56a8bf187763f82fc2a4503d81f6e1..072b4f6d7bd4518b36be283a609dcf21fc086876 100644
--- a/app/src/main/res/layout/action_overflow_popwindow.xml
+++ b/app/src/main/res/layout/action_overflow_popwindow.xml
@@ -1,7 +1,7 @@
@@ -21,7 +21,7 @@
android:gravity="center"
android:text="@string/text_Setting"
android:textColor="@color/black"
- android:textSize="20sp" />
+ android:textSize="22sp" />
+ android:textSize="22sp" />
+ android:textSize="22sp" />
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 2e3fd55e6ffb34784eae47f94b880156a4151439..7ab261edd3865c883b1b0e008ef2c926bdd8be83 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -104,4 +104,10 @@
tools:ignore="MissingConstraints" />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml
index b11bfa7c67e39666fbe6f4b2cc34c432bd2e2246..2271e2971d6fb50b0f4a95a894294fbfc170f21c 100644
--- a/app/src/main/res/layout/activity_setting.xml
+++ b/app/src/main/res/layout/activity_setting.xml
@@ -2,33 +2,40 @@
diff --git a/app/src/main/res/layout/listview_item.xml b/app/src/main/res/layout/listview_item.xml
index 74d05d4f49d5f1a782f1e215683dbf4bcf7f840c..d7dffeadf27d0323198f643cfa2ed8f6426f67c6 100644
--- a/app/src/main/res/layout/listview_item.xml
+++ b/app/src/main/res/layout/listview_item.xml
@@ -64,8 +64,9 @@
android:id="@+id/is_install"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/text_Installed"
+ android:text="@string/text_Uninstalled"
android:textColor="@color/black"
+ android:paddingRight="10dp"
android:textSize="15sp"
android:visibility="gone" />
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0c72e3409dee8bd90b5801ce58020c16685688a3..add19c7c7726ff1b0ce3654203bde071258ef71e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -9,13 +9,16 @@
关闭
1.
搜索
- 支持输入网络链接获取或直接输入Json\n格式:"[{'id':1,'appname':'name','apppackage':'package'}]"
+ [{"id": 1,"appName": "","appPackage": "","downloadUri": "https://---"}],请用https地址
包名中包含此处关键字的将不显示,多个用英文逗号隔开
网络配置
本地配置
已安装
未安装
打开
+ 下载暂停
+ 等待下载
+ 下载
本地应用
更多
刷新
@@ -33,7 +36,11 @@
请输入你要设置的AppName
保存成功
本地缓存数据错误
- 请检查你的输入!既不是链接也不是正确Json
+ 请检查你的输入!既不是链接也不是正确Json!
+ 不是https地址!
+ 下载地址错误!
+ 启动下载失败,请检查下载地址是否正确!
+ 格式有误,字段不能为空!
初始化自定义包名配置错误!
设置AppName
未更改
@@ -42,5 +49,7 @@
当前使用本地缓存
加载中请稍后
欢迎使用该软件\n一.点击Item可打开应用设置界面。\n二.长按Item可弹出自定义设置应用名弹窗。\n三.应用列表可Json导入、网络获取、使用本地已安装应用。\n
+ 需要文件读写权限进行文件下载及获取电话状态权限!
+ 是否进入应用信息开启必要权限?
\n\n如有疑问,请联系:lovemoclub@163.com\
\ No newline at end of file
diff --git a/app/src/main/res/xml/file_path.xml b/app/src/main/res/xml/file_path.xml
new file mode 100644
index 0000000000000000000000000000000000000000..71990ad0935404fa7c7d63b4473e31aec7ccff73
--- /dev/null
+++ b/app/src/main/res/xml/file_path.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 3512dd371cd79f96e5362bd7c75236c02a1368c2..9a4a4282d4bb0e4d8e0d92866f3ba1d804566646 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.4.1'
+ classpath 'com.android.tools.build:gradle:3.6.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 14a62b14318932dc80dda7f1caede7f91223528d..4786247bb49511a835e6eff5dcae733cb087a8e9 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri May 03 16:50:12 CST 2019
+#Tue Mar 24 09:46:10 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip