AK\A9 Launcher
authorkfl_614 <kfl_614@163.com>
Wed, 19 Aug 2020 07:14:03 +0000 (15:14 +0800)
committerkfl_614 <kfl_614@163.com>
Wed, 19 Aug 2020 07:14:03 +0000 (15:14 +0800)
201 files changed:
.gitignore [new file with mode: 0644]
.idea/$PROJECT_FILE$ [new file with mode: 0644]
.idea/codeStyles/Project.xml [new file with mode: 0644]
.idea/gradle.xml [new file with mode: 0644]
.idea/jarRepositories.xml [new file with mode: 0644]
.idea/misc.xml [new file with mode: 0644]
.idea/qaplug_profiles.xml [new file with mode: 0644]
.idea/runConfigurations.xml [new file with mode: 0644]
app/.gitignore [new file with mode: 0644]
app/EQC_G5.jks [new file with mode: 0644]
app/IcA9Launcher/release/IcA9Launcher_V1_5.0_202008171714_release.apk [new file with mode: 0644]
app/IcA9Launcher/release/output-metadata.json [new file with mode: 0644]
app/IcAkLauncher/release/IcAkLauncher_V1_3.0_202008072245_release.apk [new file with mode: 0644]
app/IcAkLauncher/release/output-metadata.json [new file with mode: 0644]
app/build.gradle [new file with mode: 0644]
app/proguard-rules.pro [new file with mode: 0644]
app/src/androidTest/java/com/ic/ak/launcher/ExampleInstrumentedTest.java [new file with mode: 0644]
app/src/main/AndroidManifest.xml [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/LauncherApp.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/app/AppConfig.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/app/AppDispose.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/app/AppItem.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/battery/BatteryConnectStateEvent.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/battery/BatteryDispose.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/hardware/HardwareDispose.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/phone/CallPhone.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/phone/LoopThread.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/phone/PhoneDispose.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/play/SoundPlayUtils.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/data/time/TimeDispose.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/DialogActivity.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/FragmentAdapter.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/IndicatorAdapter.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/MainActivity.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/BatteryLowFragment.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/BatteryLowManage.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/DialogDismissEvent.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/NotificationDialogFragment.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/NotificationDialogManage.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/SedentaryAlarmDialogFragment.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/SedentaryDialogManage.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/SlipTipsFragment.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/SlipTipsManage.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/TextShowDialogFragment.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/dialog/TextShowDialogManage.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/fragment/AppFragment.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/fragment/AppVoicePlayEvent.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/fragment/MainA9Fragment.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/fragment/MainA9ViewModel.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/fragment/MainFragment.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/fragment/MainViewModel.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/ui/notification/NotificationActivity.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/util/CrashHandler.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/util/IcLog.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/util/SPUtils.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/util/ServiceUtil.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/util/ThreadPool.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/widget/MultiRowTextView.java [new file with mode: 0644]
app/src/main/java/com/ic/ak/launcher/widget/WidgetHeadLayout.java [new file with mode: 0644]
app/src/main/res/drawable-v24/ic_launcher_foreground.xml [new file with mode: 0644]
app/src/main/res/drawable/battery_charging_anim_a9.xml [new file with mode: 0644]
app/src/main/res/drawable/battery_charging_anim_ak.xml [new file with mode: 0644]
app/src/main/res/drawable/ic_close_24.xml [new file with mode: 0644]
app/src/main/res/drawable/ic_launcher_background.xml [new file with mode: 0644]
app/src/main/res/drawable/ic_transparent_circle.xml [new file with mode: 0644]
app/src/main/res/drawable/ic_white_circle.xml [new file with mode: 0644]
app/src/main/res/drawable/shape_dialog_notification_bg.xml [new file with mode: 0644]
app/src/main/res/drawable/shape_dialog_notification_button_close.xml [new file with mode: 0644]
app/src/main/res/drawable/shape_dialog_notification_button_open.xml [new file with mode: 0644]
app/src/main/res/drawable/shape_dialog_notification_line.xml [new file with mode: 0644]
app/src/main/res/drawable/shape_item_bg.xml [new file with mode: 0644]
app/src/main/res/drawable/shape_main_contacts_bg.xml [new file with mode: 0644]
app/src/main/res/drawable/shape_main_week_bg.xml [new file with mode: 0644]
app/src/main/res/drawable/shape_notification_button_bg.xml [new file with mode: 0644]
app/src/main/res/drawable/shape_notification_text_bg.xml [new file with mode: 0644]
app/src/main/res/layout/activity_a9_main.xml [new file with mode: 0644]
app/src/main/res/layout/activity_dialog.xml [new file with mode: 0644]
app/src/main/res/layout/activity_main.xml [new file with mode: 0644]
app/src/main/res/layout/activity_notification.xml [new file with mode: 0644]
app/src/main/res/layout/dialog_notification.xml [new file with mode: 0644]
app/src/main/res/layout/dialog_sedentary_alarm.xml [new file with mode: 0644]
app/src/main/res/layout/dialog_text_show_a9.xml [new file with mode: 0644]
app/src/main/res/layout/fragment_a9_app.xml [new file with mode: 0644]
app/src/main/res/layout/fragment_a9_main.xml [new file with mode: 0644]
app/src/main/res/layout/fragment_app.xml [new file with mode: 0644]
app/src/main/res/layout/fragment_image_battery_low.xml [new file with mode: 0644]
app/src/main/res/layout/fragment_image_slip.xml [new file with mode: 0644]
app/src/main/res/layout/fragment_main.xml [new file with mode: 0644]
app/src/main/res/layout/item_indicator_layout.xml [new file with mode: 0644]
app/src/main/res/layout/widget_head_layout.xml [new file with mode: 0644]
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml [new file with mode: 0644]
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml [new file with mode: 0644]
app/src/main/res/mipmap-hdpi/ic_launcher.png [new file with mode: 0644]
app/src/main/res/mipmap-hdpi/ic_launcher_round.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_album.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_alipay.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_app_bind.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_call_records.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_camera.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_dial.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_healthy.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_hotline.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_message.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_sedentary.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_setting.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_sleep.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_app_icon_walk.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_battery_0.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_battery_1.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_battery_2.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_battery_3.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_battery_4.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_battery_5.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_data_transport_0.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_data_transport_1.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_data_transport_2.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_data_transport_3.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_phone_type_2g.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_phone_type_3g.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_phone_type_4g.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_phone_type_u.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_sedentary_affirm.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_sedentary_alarm_main.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_sedentary_close.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_signal_0.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_signal_1.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_signal_2.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_signal_3.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_signal_4.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ak_signal_x.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/ic_head_left_arrows.png [new file with mode: 0644]
app/src/main/res/mipmap-ldpi/low_power_battery.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_app_icon_album.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_app_icon_camera.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_app_icon_contacts.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_app_icon_dial.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_app_icon_healthy.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_app_icon_message.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_app_icon_setting.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_app_icon_temp.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_app_icon_walk.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_battery_0.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_battery_1.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_battery_2.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_battery_3.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_battery_4.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_battery_5.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_heartrate_icon.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_pedometer.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_phone_type_2g.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_phone_type_3g.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_phone_type_4g.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_phone_type_u.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_signal_0.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_signal_1.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_signal_2.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_signal_3.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_signal_4.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/a9_signal_x.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/ak_signal_nosim.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/ic_band_off.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/ic_launcher.png [new file with mode: 0644]
app/src/main/res/mipmap-mdpi/ic_launcher_round.png [new file with mode: 0644]
app/src/main/res/mipmap-xhdpi/ic_launcher.png [new file with mode: 0644]
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png [new file with mode: 0644]
app/src/main/res/mipmap-xxhdpi/ic_launcher.png [new file with mode: 0644]
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png [new file with mode: 0644]
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png [new file with mode: 0644]
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png [new file with mode: 0644]
app/src/main/res/raw-en/chrg_connect.mp3 [new file with mode: 0644]
app/src/main/res/raw-en/chrg_remove.mp3 [new file with mode: 0644]
app/src/main/res/raw/a9_antioff.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_album.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_bind.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_call_records.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_camera.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_dial.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_health.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_living_home.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_message.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_ped.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_sedentary.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_setting.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_sleep.mp3 [new file with mode: 0644]
app/src/main/res/raw/ak_app_voice_zfb.mp3 [new file with mode: 0644]
app/src/main/res/raw/chrg_complete.mp3 [new file with mode: 0644]
app/src/main/res/raw/chrg_connect.mp3 [new file with mode: 0644]
app/src/main/res/raw/chrg_remove.mp3 [new file with mode: 0644]
app/src/main/res/values-en/strings.xml [new file with mode: 0644]
app/src/main/res/values-zh-rCN/strings.xml [new file with mode: 0644]
app/src/main/res/values/colors.xml [new file with mode: 0644]
app/src/main/res/values/strings.xml [new file with mode: 0644]
app/src/main/res/values/styles.xml [new file with mode: 0644]
app/src/test/java/com/ic/ak/launcher/ExampleUnitTest.java [new file with mode: 0644]
build.gradle [new file with mode: 0644]
gradle.properties [new file with mode: 0644]
gradle/wrapper/gradle-wrapper.jar [new file with mode: 0644]
gradle/wrapper/gradle-wrapper.properties [new file with mode: 0644]
gradlew [new file with mode: 0644]
gradlew.bat [new file with mode: 0644]
settings.gradle [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..603b140
--- /dev/null
@@ -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/$PROJECT_FILE$ b/.idea/$PROJECT_FILE$
new file mode 100644 (file)
index 0000000..58b7e3e
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AnalysisProjectProfileManager">
+    <option name="PROJECT_PROFILE" />
+    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
+    <list size="0" />
+  </component>
+  <component name="SuppressionsComponent">
+    <option name="suppComments" value="[]" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644 (file)
index 0000000..681f41a
--- /dev/null
@@ -0,0 +1,116 @@
+<component name="ProjectCodeStyleConfiguration">
+  <code_scheme name="Project" version="173">
+    <codeStyleSettings language="XML">
+      <indentOptions>
+        <option name="CONTINUATION_INDENT_SIZE" value="4" />
+      </indentOptions>
+      <arrangement>
+        <rules>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>xmlns:android</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>xmlns:.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*:id</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*:name</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>name</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>style</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>ANDROID_ATTRIBUTE_ORDER</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>.*</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+        </rules>
+      </arrangement>
+    </codeStyleSettings>
+  </code_scheme>
+</component>
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644 (file)
index 0000000..c820ab9
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleMigrationSettings" migrationVersion="1" />
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="testRunner" value="PLATFORM" />
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="gradleJvm" value="1.8 (2)" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+          </set>
+        </option>
+        <option name="resolveModulePerSourceSet" value="false" />
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644 (file)
index 0000000..a5f05cd
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RemoteRepositoriesConfiguration">
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Maven Central repository" />
+      <option name="url" value="https://repo1.maven.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jboss.community" />
+      <option name="name" value="JBoss Community repository" />
+      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="BintrayJCenter" />
+      <option name="name" value="BintrayJCenter" />
+      <option name="url" value="https://jcenter.bintray.com/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="Google" />
+      <option name="name" value="Google" />
+      <option name="url" value="https://dl.google.com/dl/android/maven2/" />
+    </remote-repository>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644 (file)
index 0000000..fdba094
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="FindBugsConfigurable">
+    <option name="make" value="true" />
+    <option name="effort" value="default" />
+    <option name="priority" value="Medium" />
+    <option name="excludeFilter" value="" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="ProjectType">
+    <option name="id" value="Android" />
+  </component>
+  <component name="SuppressionsComponent">
+    <option name="suppComments" value="[]" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/qaplug_profiles.xml b/.idea/qaplug_profiles.xml
new file mode 100644 (file)
index 0000000..3dfd21f
--- /dev/null
@@ -0,0 +1,465 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AnalysisProjectProfileManager">
+    <option name="PROJECT_PROFILE" value="Project Default" />
+    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
+    <scopes />
+    <profiles>
+      <profile profile_name="Project Default" version="1.0" is_locked="false">
+        <coding_rule class="AM_CREATES_EMPTY_JAR_FILE_ENTRY" level="MAJOR" enabled="true" />
+        <coding_rule class="AM_CREATES_EMPTY_ZIP_FILE_ENTRY" level="MAJOR" enabled="true" />
+        <coding_rule class="AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION" level="CRITICAL" enabled="false" />
+        <coding_rule class="BAC_BAD_APPLET_CONSTRUCTOR" level="MAJOR" enabled="false" />
+        <coding_rule class="BC_BAD_CAST_TO_ABSTRACT_COLLECTION" level="MAJOR" enabled="true" />
+        <coding_rule class="BC_BAD_CAST_TO_CONCRETE_COLLECTION" level="CRITICAL" enabled="true" />
+        <coding_rule class="BC_EQUALS_METHOD_SHOULD_WORK_FOR_ALL_OBJECTS" level="CRITICAL" enabled="true" />
+        <coding_rule class="BC_IMPOSSIBLE_CAST" level="BLOCKER" enabled="true" />
+        <coding_rule class="BC_IMPOSSIBLE_DOWNCAST" level="MAJOR" enabled="false" />
+        <coding_rule class="BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY" level="MAJOR" enabled="false" />
+        <coding_rule class="BC_IMPOSSIBLE_INSTANCEOF" level="CRITICAL" enabled="true" />
+        <coding_rule class="BC_UNCONFIRMED_CAST" level="CRITICAL" enabled="true" />
+        <coding_rule class="BC_UNCONFIRMED_CAST_OF_RETURN_VALUE" level="CRITICAL" enabled="false" />
+        <coding_rule class="BC_VACUOUS_INSTANCEOF" level="CRITICAL" enabled="true" />
+        <coding_rule class="BIT_ADD_OF_SIGNED_BYTE" level="CRITICAL" enabled="true" />
+        <coding_rule class="BIT_AND" level="CRITICAL" enabled="true" />
+        <coding_rule class="BIT_AND_ZZ" level="CRITICAL" enabled="true" />
+        <coding_rule class="BIT_IOR" level="CRITICAL" enabled="true" />
+        <coding_rule class="BIT_IOR_OF_SIGNED_BYTE" level="CRITICAL" enabled="true" />
+        <coding_rule class="BIT_SIGNED_CHECK" level="CRITICAL" enabled="true" />
+        <coding_rule class="BIT_SIGNED_CHECK_HIGH_BIT" level="CRITICAL" enabled="true" />
+        <coding_rule class="BOA_BADLY_OVERRIDDEN_ADAPTER" level="CRITICAL" enabled="true" />
+        <coding_rule class="BSHIFT_WRONG_ADD_PRIORITY" level="MAJOR" enabled="false" />
+        <coding_rule class="BX_BOXING_IMMEDIATELY_UNBOXED" level="MAJOR" enabled="true" />
+        <coding_rule class="BX_BOXING_IMMEDIATELY_UNBOXED_TO_PERFORM_COERCION" level="MAJOR" enabled="true" />
+        <coding_rule class="BX_UNBOXED_AND_COERCED_FOR_TERNARY_OPERATOR" level="MAJOR" enabled="true" />
+        <coding_rule class="BX_UNBOXING_IMMEDIATELY_REBOXED" level="CRITICAL" enabled="false" />
+        <coding_rule class="CAA_COVARIANT_ARRAY_ELEMENT_STORE" level="MAJOR" enabled="false" />
+        <coding_rule class="CAA_COVARIANT_ARRAY_FIELD" level="MAJOR" enabled="false" />
+        <coding_rule class="CAA_COVARIANT_ARRAY_LOCAL" level="MAJOR" enabled="false" />
+        <coding_rule class="CAA_COVARIANT_ARRAY_RETURN" level="MAJOR" enabled="false" />
+        <coding_rule class="CD_CIRCULAR_DEPENDENCY" level="MAJOR" enabled="false" />
+        <coding_rule class="CI_CONFUSED_INHERITANCE" level="MINOR" enabled="true" />
+        <coding_rule class="CNT_ROUGH_CONSTANT_VALUE" level="MAJOR" enabled="false" />
+        <coding_rule class="CN_IDIOM" level="MAJOR" enabled="true" />
+        <coding_rule class="CN_IDIOM_NO_SUPER_CALL" level="MAJOR" enabled="true" />
+        <coding_rule class="CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE" level="MAJOR" enabled="true" />
+        <coding_rule class="CO_ABSTRACT_SELF" level="MAJOR" enabled="true" />
+        <coding_rule class="CO_COMPARETO_INCORRECT_FLOATING" level="MAJOR" enabled="false" />
+        <coding_rule class="CO_COMPARETO_RESULTS_MIN_VALUE" level="CRITICAL" enabled="false" />
+        <coding_rule class="CO_SELF_NO_OBJECT" level="MAJOR" enabled="true" />
+        <coding_rule class="DB_DUPLICATE_BRANCHES" level="CRITICAL" enabled="true" />
+        <coding_rule class="DB_DUPLICATE_SWITCH_CLAUSES" level="CRITICAL" enabled="true" />
+        <coding_rule class="DC_DOUBLECHECK" level="MAJOR" enabled="true" />
+        <coding_rule class="DC_PARTIALLY_CONSTRUCTED" level="MAJOR" enabled="false" />
+        <coding_rule class="DE_MIGHT_DROP" level="MAJOR" enabled="true" />
+        <coding_rule class="DE_MIGHT_IGNORE" level="MAJOR" enabled="true" />
+        <coding_rule class="DLS_DEAD_LOCAL_INCREMENT_IN_RETURN" level="MAJOR" enabled="false" />
+        <coding_rule class="DLS_DEAD_LOCAL_STORE" level="CRITICAL" enabled="true" />
+        <coding_rule class="DLS_DEAD_LOCAL_STORE_IN_RETURN" level="CRITICAL" enabled="true" />
+        <coding_rule class="DLS_DEAD_LOCAL_STORE_OF_NULL" level="CRITICAL" enabled="true" />
+        <coding_rule class="DLS_DEAD_LOCAL_STORE_SHADOWS_FIELD" level="CRITICAL" enabled="false" />
+        <coding_rule class="DLS_DEAD_STORE_OF_CLASS_LITERAL" level="CRITICAL" enabled="true" />
+        <coding_rule class="DLS_OVERWRITTEN_INCREMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="DL_SYNCHRONIZATION_ON_BOOLEAN" level="CRITICAL" enabled="true" />
+        <coding_rule class="DL_SYNCHRONIZATION_ON_BOXED_PRIMITIVE" level="CRITICAL" enabled="true" />
+        <coding_rule class="DL_SYNCHRONIZATION_ON_SHARED_CONSTANT" level="CRITICAL" enabled="true" />
+        <coding_rule class="DL_SYNCHRONIZATION_ON_UNSHARED_BOXED_PRIMITIVE" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_ANNOTATION_IS_NOT_VISIBLE_TO_REFLECTION" level="MAJOR" enabled="true" />
+        <coding_rule class="DMI_ARGUMENTS_WRONG_ORDER" level="CRITICAL" enabled="false" />
+        <coding_rule class="DMI_BAD_MONTH" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_BIGDECIMAL_CONSTRUCTED_FROM_DOUBLE" level="CRITICAL" enabled="false" />
+        <coding_rule class="DMI_BLOCKING_METHODS_ON_URL" level="BLOCKER" enabled="true" />
+        <coding_rule class="DMI_CALLING_NEXT_FROM_HASNEXT" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_COLLECTIONS_SHOULD_NOT_CONTAIN_THEMSELVES" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_COLLECTION_OF_URLS" level="BLOCKER" enabled="true" />
+        <coding_rule class="DMI_CONSTANT_DB_PASSWORD" level="BLOCKER" enabled="true" />
+        <coding_rule class="DMI_DOH" level="CRITICAL" enabled="false" />
+        <coding_rule class="DMI_EMPTY_DB_PASSWORD" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS" level="CRITICAL" enabled="false" />
+        <coding_rule class="DMI_FUTILE_ATTEMPT_TO_CHANGE_MAXPOOL_SIZE_OF_SCHEDULED_THREAD_POOL_EXECUTOR" level="MINOR" enabled="true" />
+        <coding_rule class="DMI_HARDCODED_ABSOLUTE_FILENAME" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_INVOKING_HASHCODE_ON_ARRAY" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_INVOKING_TOSTRING_ON_ANONYMOUS_ARRAY" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_INVOKING_TOSTRING_ON_ARRAY" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_LONG_BITS_TO_DOUBLE_INVOKED_ON_INT" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_NONSERIALIZABLE_OBJECT_WRITTEN" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_RANDOM_USED_ONLY_ONCE" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_SCHEDULED_THREAD_POOL_EXECUTOR_WITH_ZERO_CORE_THREADS" level="MINOR" enabled="true" />
+        <coding_rule class="DMI_THREAD_PASSED_WHERE_RUNNABLE_EXPECTED" level="MAJOR" enabled="true" />
+        <coding_rule class="DMI_UNSUPPORTED_METHOD" level="MAJOR" enabled="true" />
+        <coding_rule class="DMI_USELESS_SUBSTRING" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION" level="CRITICAL" enabled="true" />
+        <coding_rule class="DMI_VACUOUS_CALL_TO_EASYMOCK_METHOD" level="MINOR" enabled="true" />
+        <coding_rule class="DMI_VACUOUS_SELF_COLLECTION_CALL" level="CRITICAL" enabled="true" />
+        <coding_rule class="DM_BOOLEAN_CTOR" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_BOXED_PRIMITIVE_FOR_COMPARE" level="MAJOR" enabled="false" />
+        <coding_rule class="DM_BOXED_PRIMITIVE_FOR_PARSING" level="MAJOR" enabled="false" />
+        <coding_rule class="DM_BOXED_PRIMITIVE_TOSTRING" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_CONVERT_CASE" level="INFO" enabled="true" />
+        <coding_rule class="DM_DEFAULT_ENCODING" level="CRITICAL" enabled="false" />
+        <coding_rule class="DM_EXIT" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_FP_NUMBER_CTOR" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_GC" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_INVALID_MIN_MAX" level="MAJOR" enabled="false" />
+        <coding_rule class="DM_MONITOR_WAIT_ON_CONDITION" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_NEW_FOR_GETCLASS" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_NEXTINT_VIA_NEXTDOUBLE" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_NUMBER_CTOR" level="CRITICAL" enabled="true" />
+        <coding_rule class="DM_RUN_FINALIZERS_ON_EXIT" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_STRING_CTOR" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_STRING_TOSTRING" level="INFO" enabled="true" />
+        <coding_rule class="DM_STRING_VOID_CTOR" level="MAJOR" enabled="true" />
+        <coding_rule class="DM_USELESS_THREAD" level="MAJOR" enabled="true" />
+        <coding_rule class="DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED" level="MAJOR" enabled="true" />
+        <coding_rule class="DP_DO_INSIDE_DO_PRIVILEGED" level="MAJOR" enabled="true" />
+        <coding_rule class="EC_ARRAY_AND_NONARRAY" level="CRITICAL" enabled="true" />
+        <coding_rule class="EC_BAD_ARRAY_COMPARE" level="CRITICAL" enabled="true" />
+        <coding_rule class="EC_INCOMPATIBLE_ARRAY_COMPARE" level="MAJOR" enabled="false" />
+        <coding_rule class="EC_NULL_ARG" level="CRITICAL" enabled="true" />
+        <coding_rule class="EC_UNRELATED_CLASS_AND_INTERFACE" level="CRITICAL" enabled="true" />
+        <coding_rule class="EC_UNRELATED_INTERFACES" level="CRITICAL" enabled="true" />
+        <coding_rule class="EC_UNRELATED_TYPES" level="CRITICAL" enabled="true" />
+        <coding_rule class="EC_UNRELATED_TYPES_USING_POINTER_EQUALITY" level="CRITICAL" enabled="true" />
+        <coding_rule class="EI_EXPOSE_REP" level="MAJOR" enabled="true" />
+        <coding_rule class="EI_EXPOSE_REP2" level="MAJOR" enabled="true" />
+        <coding_rule class="EI_EXPOSE_STATIC_REP2" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_ABSTRACT_SELF" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_ALWAYS_FALSE" level="BLOCKER" enabled="true" />
+        <coding_rule class="EQ_ALWAYS_TRUE" level="BLOCKER" enabled="true" />
+        <coding_rule class="EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_COMPARETO_USE_OBJECT_EQUALS" level="CRITICAL" enabled="true" />
+        <coding_rule class="EQ_COMPARING_CLASS_NAMES" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_DOESNT_OVERRIDE_EQUALS" level="MAJOR" enabled="false" />
+        <coding_rule class="EQ_DONT_DEFINE_EQUALS_FOR_ENUM" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_GETCLASS_AND_CLASS_CONSTANT" level="CRITICAL" enabled="true" />
+        <coding_rule class="EQ_OTHER_NO_OBJECT" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_OTHER_USE_OBJECT" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_SELF_NO_OBJECT" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_SELF_USE_OBJECT" level="MAJOR" enabled="true" />
+        <coding_rule class="EQ_UNUSUAL" level="MINOR" enabled="true" />
+        <coding_rule class="ES_COMPARING_PARAMETER_STRING_WITH_EQ" level="MAJOR" enabled="true" />
+        <coding_rule class="ES_COMPARING_STRINGS_WITH_EQ" level="MAJOR" enabled="true" />
+        <coding_rule class="ESync_EMPTY_SYNC" level="MAJOR" enabled="true" />
+        <coding_rule class="FB_MISSING_EXPECTED_WARNING" level="CRITICAL" enabled="false" />
+        <coding_rule class="FB_UNEXPECTED_WARNING" level="CRITICAL" enabled="false" />
+        <coding_rule class="FE_FLOATING_POINT_EQUALITY" level="CRITICAL" enabled="true" />
+        <coding_rule class="FE_TEST_IF_EQUAL_TO_NOT_A_NUMBER" level="CRITICAL" enabled="true" />
+        <coding_rule class="FI_EMPTY" level="MAJOR" enabled="true" />
+        <coding_rule class="FI_EXPLICIT_INVOCATION" level="MAJOR" enabled="true" />
+        <coding_rule class="FI_FINALIZER_NULLS_FIELDS" level="MAJOR" enabled="true" />
+        <coding_rule class="FI_FINALIZER_ONLY_NULLS_FIELDS" level="MAJOR" enabled="true" />
+        <coding_rule class="FI_MISSING_SUPER_CALL" level="MAJOR" enabled="true" />
+        <coding_rule class="FI_NULLIFY_SUPER" level="CRITICAL" enabled="true" />
+        <coding_rule class="FI_PUBLIC_SHOULD_BE_PROTECTED" level="MAJOR" enabled="true" />
+        <coding_rule class="FI_USELESS" level="MINOR" enabled="true" />
+        <coding_rule class="FL_MATH_USING_FLOAT_PRECISION" level="CRITICAL" enabled="true" />
+        <coding_rule class="GC_UNCHECKED_TYPE_IN_GENERIC_CALL" level="CRITICAL" enabled="true" />
+        <coding_rule class="GC_UNRELATED_TYPES" level="CRITICAL" enabled="true" />
+        <coding_rule class="HE_EQUALS_NO_HASHCODE" level="MAJOR" enabled="true" />
+        <coding_rule class="HE_EQUALS_USE_HASHCODE" level="CRITICAL" enabled="true" />
+        <coding_rule class="HE_HASHCODE_NO_EQUALS" level="CRITICAL" enabled="true" />
+        <coding_rule class="HE_HASHCODE_USE_OBJECT_EQUALS" level="CRITICAL" enabled="true" />
+        <coding_rule class="HE_INHERITS_EQUALS_USE_HASHCODE" level="CRITICAL" enabled="true" />
+        <coding_rule class="HE_SIGNATURE_DECLARES_HASHING_OF_UNHASHABLE_CLASS" level="CRITICAL" enabled="true" />
+        <coding_rule class="HE_USE_OF_UNHASHABLE_CLASS" level="CRITICAL" enabled="true" />
+        <coding_rule class="HRS_REQUEST_PARAMETER_TO_COOKIE" level="MAJOR" enabled="true" />
+        <coding_rule class="HRS_REQUEST_PARAMETER_TO_HTTP_HEADER" level="MAJOR" enabled="true" />
+        <coding_rule class="HSC_HUGE_SHARED_STRING_CONSTANT" level="CRITICAL" enabled="true" />
+        <coding_rule class="IA_AMBIGUOUS_INVOCATION_OF_INHERITED_OR_OUTER_METHOD" level="MAJOR" enabled="true" />
+        <coding_rule class="ICAST_BAD_SHIFT_AMOUNT" level="CRITICAL" enabled="true" />
+        <coding_rule class="ICAST_IDIV_CAST_TO_DOUBLE" level="CRITICAL" enabled="true" />
+        <coding_rule class="ICAST_INTEGER_MULTIPLY_CAST_TO_LONG" level="CRITICAL" enabled="true" />
+        <coding_rule class="ICAST_INT_2_LONG_AS_INSTANT" level="CRITICAL" enabled="false" />
+        <coding_rule class="ICAST_INT_CAST_TO_DOUBLE_PASSED_TO_CEIL" level="CRITICAL" enabled="true" />
+        <coding_rule class="ICAST_INT_CAST_TO_FLOAT_PASSED_TO_ROUND" level="CRITICAL" enabled="true" />
+        <coding_rule class="ICAST_QUESTIONABLE_UNSIGNED_RIGHT_SHIFT" level="CRITICAL" enabled="true" />
+        <coding_rule class="IC_INIT_CIRCULARITY" level="CRITICAL" enabled="true" />
+        <coding_rule class="IC_SUPERCLASS_USES_SUBCLASS_DURING_INITIALIZATION" level="MAJOR" enabled="true" />
+        <coding_rule class="IIL_ELEMENTS_GET_LENGTH_IN_LOOP" level="MAJOR" enabled="false" />
+        <coding_rule class="IIL_PATTERN_COMPILE_IN_LOOP" level="MAJOR" enabled="false" />
+        <coding_rule class="IIL_PATTERN_COMPILE_IN_LOOP_INDIRECT" level="MAJOR" enabled="false" />
+        <coding_rule class="IIL_PREPARE_STATEMENT_IN_LOOP" level="MAJOR" enabled="false" />
+        <coding_rule class="IIO_INEFFICIENT_INDEX_OF" level="MAJOR" enabled="false" />
+        <coding_rule class="IIO_INEFFICIENT_LAST_INDEX_OF" level="MAJOR" enabled="false" />
+        <coding_rule class="IJU_ASSERT_METHOD_INVOKED_FROM_RUN_METHOD" level="CRITICAL" enabled="true" />
+        <coding_rule class="IJU_BAD_SUITE_METHOD" level="CRITICAL" enabled="true" />
+        <coding_rule class="IJU_NO_TESTS" level="CRITICAL" enabled="true" />
+        <coding_rule class="IJU_SETUP_NO_SUPER" level="CRITICAL" enabled="true" />
+        <coding_rule class="IJU_SUITE_NOT_STATIC" level="CRITICAL" enabled="true" />
+        <coding_rule class="IJU_TEARDOWN_NO_SUPER" level="CRITICAL" enabled="true" />
+        <coding_rule class="IL_CONTAINER_ADDED_TO_ITSELF" level="CRITICAL" enabled="true" />
+        <coding_rule class="IL_INFINITE_LOOP" level="CRITICAL" enabled="true" />
+        <coding_rule class="IL_INFINITE_RECURSIVE_LOOP" level="CRITICAL" enabled="true" />
+        <coding_rule class="IMA_INEFFICIENT_MEMBER_ACCESS" level="MAJOR" enabled="false" />
+        <coding_rule class="IMSE_DONT_CATCH_IMSE" level="MAJOR" enabled="true" />
+        <coding_rule class="IM_AVERAGE_COMPUTATION_COULD_OVERFLOW" level="CRITICAL" enabled="true" />
+        <coding_rule class="IM_BAD_CHECK_FOR_ODD" level="CRITICAL" enabled="true" />
+        <coding_rule class="IM_MULTIPLYING_RESULT_OF_IREM" level="CRITICAL" enabled="true" />
+        <coding_rule class="INT_BAD_COMPARISON_WITH_INT_VALUE" level="CRITICAL" enabled="false" />
+        <coding_rule class="INT_BAD_COMPARISON_WITH_NONNEGATIVE_VALUE" level="CRITICAL" enabled="true" />
+        <coding_rule class="INT_BAD_COMPARISON_WITH_SIGNED_BYTE" level="CRITICAL" enabled="true" />
+        <coding_rule class="INT_BAD_REM_BY_1" level="CRITICAL" enabled="true" />
+        <coding_rule class="INT_VACUOUS_BIT_OPERATION" level="CRITICAL" enabled="true" />
+        <coding_rule class="INT_VACUOUS_COMPARISON" level="CRITICAL" enabled="true" />
+        <coding_rule class="IO_APPENDING_TO_OBJECT_OUTPUT_STREAM" level="CRITICAL" enabled="true" />
+        <coding_rule class="IP_PARAMETER_IS_DEAD_BUT_OVERWRITTEN" level="CRITICAL" enabled="true" />
+        <coding_rule class="IS2_INCONSISTENT_SYNC" level="CRITICAL" enabled="true" />
+        <coding_rule class="ISC_INSTANTIATE_STATIC_CLASS" level="MAJOR" enabled="true" />
+        <coding_rule class="IS_FIELD_NOT_GUARDED" level="CRITICAL" enabled="true" />
+        <coding_rule class="ITA_INEFFICIENT_TO_ARRAY" level="CRITICAL" enabled="true" />
+        <coding_rule class="IT_NO_SUCH_ELEMENT" level="MINOR" enabled="true" />
+        <coding_rule class="J2EE_STORE_OF_NON_SERIALIZABLE_OBJECT_INTO_SESSION" level="CRITICAL" enabled="true" />
+        <coding_rule class="JCIP_FIELD_ISNT_FINAL_IN_IMMUTABLE_CLASS" level="MINOR" enabled="true" />
+        <coding_rule class="JLM_JSR166_LOCK_MONITORENTER" level="CRITICAL" enabled="true" />
+        <coding_rule class="JLM_JSR166_UTILCONCURRENT_MONITORENTER" level="CRITICAL" enabled="false" />
+        <coding_rule class="JML_JSR166_CALLING_WAIT_RATHER_THAN_AWAIT" level="CRITICAL" enabled="false" />
+        <coding_rule class="LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE" level="MAJOR" enabled="false" />
+        <coding_rule class="LI_LAZY_INIT_STATIC" level="CRITICAL" enabled="true" />
+        <coding_rule class="LI_LAZY_INIT_UPDATE_STATIC" level="CRITICAL" enabled="true" />
+        <coding_rule class="ME_ENUM_FIELD_SETTER" level="MAJOR" enabled="false" />
+        <coding_rule class="ME_MUTABLE_ENUM_FIELD" level="MAJOR" enabled="false" />
+        <coding_rule class="MF_CLASS_MASKS_FIELD" level="MAJOR" enabled="true" />
+        <coding_rule class="MF_METHOD_MASKS_FIELD" level="MAJOR" enabled="true" />
+        <coding_rule class="ML_SYNC_ON_FIELD_TO_GUARD_CHANGING_THAT_FIELD" level="MAJOR" enabled="true" />
+        <coding_rule class="ML_SYNC_ON_UPDATED_FIELD" level="MAJOR" enabled="true" />
+        <coding_rule class="MSF_MUTABLE_SERVLET_FIELD" level="MAJOR" enabled="true" />
+        <coding_rule class="MS_CANNOT_BE_FINAL" level="MAJOR" enabled="true" />
+        <coding_rule class="MS_EXPOSE_REP" level="CRITICAL" enabled="true" />
+        <coding_rule class="MS_FINAL_PKGPROTECT" level="MAJOR" enabled="true" />
+        <coding_rule class="MS_MUTABLE_ARRAY" level="MAJOR" enabled="true" />
+        <coding_rule class="MS_MUTABLE_COLLECTION" level="MAJOR" enabled="false" />
+        <coding_rule class="MS_MUTABLE_COLLECTION_PKGPROTECT" level="MAJOR" enabled="false" />
+        <coding_rule class="MS_MUTABLE_HASHTABLE" level="MAJOR" enabled="true" />
+        <coding_rule class="MS_OOI_PKGPROTECT" level="MAJOR" enabled="true" />
+        <coding_rule class="MS_PKGPROTECT" level="MAJOR" enabled="true" />
+        <coding_rule class="MS_SHOULD_BE_FINAL" level="MAJOR" enabled="true" />
+        <coding_rule class="MS_SHOULD_BE_REFACTORED_TO_BE_FINAL" level="CRITICAL" enabled="false" />
+        <coding_rule class="MTIA_SUSPECT_SERVLET_INSTANCE_FIELD" level="CRITICAL" enabled="true" />
+        <coding_rule class="MTIA_SUSPECT_STRUTS_INSTANCE_FIELD" level="CRITICAL" enabled="true" />
+        <coding_rule class="MWN_MISMATCHED_NOTIFY" level="CRITICAL" enabled="true" />
+        <coding_rule class="MWN_MISMATCHED_WAIT" level="CRITICAL" enabled="true" />
+        <coding_rule class="NM_BAD_EQUAL" level="MAJOR" enabled="false" />
+        <coding_rule class="NM_CLASS_NAMING_CONVENTION" level="MAJOR" enabled="false" />
+        <coding_rule class="NM_CLASS_NOT_EXCEPTION" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_CONFUSING" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_FIELD_NAMING_CONVENTION" level="MAJOR" enabled="false" />
+        <coding_rule class="NM_FUTURE_KEYWORD_USED_AS_IDENTIFIER" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_FUTURE_KEYWORD_USED_AS_MEMBER_IDENTIFIER" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_LCASE_HASHCODE" level="MAJOR" enabled="false" />
+        <coding_rule class="NM_LCASE_TOSTRING" level="MAJOR" enabled="false" />
+        <coding_rule class="NM_METHOD_CONSTRUCTOR_CONFUSION" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_METHOD_NAMING_CONVENTION" level="MAJOR" enabled="false" />
+        <coding_rule class="NM_SAME_SIMPLE_NAME_AS_INTERFACE" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_SAME_SIMPLE_NAME_AS_SUPERCLASS" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_VERY_CONFUSING" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_VERY_CONFUSING_INTENTIONAL" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_WRONG_PACKAGE" level="MAJOR" enabled="true" />
+        <coding_rule class="NM_WRONG_PACKAGE_INTENTIONAL" level="MAJOR" enabled="true" />
+        <coding_rule class="NN_NAKED_NOTIFY" level="CRITICAL" enabled="true" />
+        <coding_rule class="NOISE_FIELD_REFERENCE" level="MAJOR" enabled="false" />
+        <coding_rule class="NOISE_METHOD_CALL" level="MAJOR" enabled="false" />
+        <coding_rule class="NOISE_NULL_DEREFERENCE" level="MAJOR" enabled="false" />
+        <coding_rule class="NOISE_OPERATION" level="MAJOR" enabled="false" />
+        <coding_rule class="NO_NOTIFY_NOT_NOTIFYALL" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_ALWAYS_NULL" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_ALWAYS_NULL_EXCEPTION" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_ARGUMENT_MIGHT_BE_NULL" level="MAJOR" enabled="true" />
+        <coding_rule class="NP_BOOLEAN_RETURN_NULL" level="MAJOR" enabled="true" />
+        <coding_rule class="NP_CLONE_COULD_RETURN_NULL" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_CLOSING_NULL" level="MAJOR" enabled="false" />
+        <coding_rule class="NP_DEREFERENCE_OF_READLINE_VALUE" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_EQUALS_SHOULD_HANDLE_NULL_ARGUMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_GUARANTEED_DEREF" level="BLOCKER" enabled="true" />
+        <coding_rule class="NP_GUARANTEED_DEREF_ON_EXCEPTION_PATH" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_IMMEDIATE_DEREFERENCE_OF_READLINE" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_LOAD_OF_KNOWN_NULL_VALUE" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_METHOD_PARAMETER_TIGHTENS_ANNOTATION" level="MAJOR" enabled="false" />
+        <coding_rule class="NP_METHOD_RETURN_RELAXING_ANNOTATION" level="MAJOR" enabled="false" />
+        <coding_rule class="NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" level="CRITICAL" enabled="false" />
+        <coding_rule class="NP_NONNULL_PARAM_VIOLATION" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_NONNULL_RETURN_VIOLATION" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_NULL_INSTANCEOF" level="BLOCKER" enabled="true" />
+        <coding_rule class="NP_NULL_ON_SOME_PATH" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_NULL_ON_SOME_PATH_EXCEPTION" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_NULL_PARAM_DEREF" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_NULL_PARAM_DEREF_NONVIRTUAL" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_OPTIONAL_RETURN_NULL" level="MAJOR" enabled="false" />
+        <coding_rule class="NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_STORE_INTO_NONNULL_FIELD" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_SYNC_AND_NULL_CHECK_FIELD" level="MAJOR" enabled="true" />
+        <coding_rule class="NP_TOSTRING_COULD_RETURN_NULL" level="CRITICAL" enabled="true" />
+        <coding_rule class="NP_UNWRITTEN_FIELD" level="MAJOR" enabled="false" />
+        <coding_rule class="NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD" level="CRITICAL" enabled="false" />
+        <coding_rule class="NS_DANGEROUS_NON_SHORT_CIRCUIT" level="CRITICAL" enabled="true" />
+        <coding_rule class="NS_NON_SHORT_CIRCUIT" level="MAJOR" enabled="true" />
+        <coding_rule class="OBL_UNSATISFIED_OBLIGATION" level="CRITICAL" enabled="false" />
+        <coding_rule class="OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE" level="CRITICAL" enabled="false" />
+        <coding_rule class="ODR_OPEN_DATABASE_RESOURCE" level="CRITICAL" enabled="true" />
+        <coding_rule class="ODR_OPEN_DATABASE_RESOURCE_EXCEPTION_PATH" level="CRITICAL" enabled="true" />
+        <coding_rule class="OS_OPEN_STREAM" level="CRITICAL" enabled="true" />
+        <coding_rule class="OS_OPEN_STREAM_EXCEPTION_PATH" level="CRITICAL" enabled="true" />
+        <coding_rule class="PS_PUBLIC_SEMAPHORES" level="CRITICAL" enabled="true" />
+        <coding_rule class="PT_ABSOLUTE_PATH_TRAVERSAL" level="CRITICAL" enabled="false" />
+        <coding_rule class="PT_RELATIVE_PATH_TRAVERSAL" level="CRITICAL" enabled="false" />
+        <coding_rule class="PZLA_PREFER_ZERO_LENGTH_ARRAYS" level="MAJOR" enabled="true" />
+        <coding_rule class="PZ_DONT_REUSE_ENTRY_OBJECTS_IN_ITERATORS" level="CRITICAL" enabled="false" />
+        <coding_rule class="QBA_QUESTIONABLE_BOOLEAN_ASSIGNMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="QF_QUESTIONABLE_FOR_LOOP" level="CRITICAL" enabled="true" />
+        <coding_rule class="RANGE_ARRAY_INDEX" level="MAJOR" enabled="false" />
+        <coding_rule class="RANGE_ARRAY_LENGTH" level="MAJOR" enabled="false" />
+        <coding_rule class="RANGE_ARRAY_OFFSET" level="MAJOR" enabled="false" />
+        <coding_rule class="RANGE_STRING_INDEX" level="MAJOR" enabled="false" />
+        <coding_rule class="RCN_REDUNDANT_COMPARISON_OF_NULL_AND_NONNULL_VALUE" level="CRITICAL" enabled="true" />
+        <coding_rule class="RCN_REDUNDANT_COMPARISON_TWO_NULL_VALUES" level="CRITICAL" enabled="true" />
+        <coding_rule class="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" level="CRITICAL" enabled="true" />
+        <coding_rule class="RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE" level="CRITICAL" enabled="true" />
+        <coding_rule class="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE" level="CRITICAL" enabled="true" />
+        <coding_rule class="RC_REF_COMPARISON" level="CRITICAL" enabled="true" />
+        <coding_rule class="RC_REF_COMPARISON_BAD_PRACTICE" level="MAJOR" enabled="false" />
+        <coding_rule class="RC_REF_COMPARISON_BAD_PRACTICE_BOOLEAN" level="MAJOR" enabled="false" />
+        <coding_rule class="REC_CATCH_EXCEPTION" level="MAJOR" enabled="true" />
+        <coding_rule class="RE_BAD_SYNTAX_FOR_REGULAR_EXPRESSION" level="CRITICAL" enabled="true" />
+        <coding_rule class="RE_CANT_USE_FILE_SEPARATOR_AS_REGULAR_EXPRESSION" level="CRITICAL" enabled="true" />
+        <coding_rule class="RE_POSSIBLE_UNINTENDED_PATTERN" level="CRITICAL" enabled="true" />
+        <coding_rule class="RI_REDUNDANT_INTERFACES" level="MAJOR" enabled="true" />
+        <coding_rule class="RR_NOT_CHECKED" level="MAJOR" enabled="true" />
+        <coding_rule class="RS_READOBJECT_SYNC" level="CRITICAL" enabled="true" />
+        <coding_rule class="RU_INVOKE_RUN" level="MAJOR" enabled="true" />
+        <coding_rule class="RV_01_TO_INT" level="MAJOR" enabled="true" />
+        <coding_rule class="RV_ABSOLUTE_VALUE_OF_HASHCODE" level="CRITICAL" enabled="true" />
+        <coding_rule class="RV_ABSOLUTE_VALUE_OF_RANDOM_INT" level="CRITICAL" enabled="true" />
+        <coding_rule class="RV_CHECK_COMPARETO_FOR_SPECIFIC_RETURN_VALUE" level="CRITICAL" enabled="false" />
+        <coding_rule class="RV_CHECK_FOR_POSITIVE_INDEXOF" level="MINOR" enabled="true" />
+        <coding_rule class="RV_DONT_JUST_NULL_CHECK_READLINE" level="MAJOR" enabled="true" />
+        <coding_rule class="RV_EXCEPTION_NOT_THROWN" level="CRITICAL" enabled="true" />
+        <coding_rule class="RV_NEGATING_RESULT_OF_COMPARETO" level="CRITICAL" enabled="false" />
+        <coding_rule class="RV_REM_OF_HASHCODE" level="CRITICAL" enabled="true" />
+        <coding_rule class="RV_REM_OF_RANDOM_INT" level="CRITICAL" enabled="true" />
+        <coding_rule class="RV_RETURN_VALUE_IGNORED" level="MINOR" enabled="true" />
+        <coding_rule class="RV_RETURN_VALUE_IGNORED_BAD_PRACTICE" level="MAJOR" enabled="true" />
+        <coding_rule class="RV_RETURN_VALUE_IGNORED_INFERRED" level="CRITICAL" enabled="false" />
+        <coding_rule class="RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT" level="MAJOR" enabled="false" />
+        <coding_rule class="RV_RETURN_VALUE_OF_PUTIFABSENT_IGNORED" level="MAJOR" enabled="false" />
+        <coding_rule class="RpC_REPEATED_CONDITIONAL_TEST" level="MAJOR" enabled="true" />
+        <coding_rule class="SA_FIELD_DOUBLE_ASSIGNMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="SA_FIELD_SELF_ASSIGNMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="SA_FIELD_SELF_COMPARISON" level="CRITICAL" enabled="true" />
+        <coding_rule class="SA_FIELD_SELF_COMPUTATION" level="CRITICAL" enabled="true" />
+        <coding_rule class="SA_LOCAL_DOUBLE_ASSIGNMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="SA_LOCAL_SELF_ASSIGNMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="SA_LOCAL_SELF_ASSIGNMENT_INSTEAD_OF_FIELD" level="CRITICAL" enabled="false" />
+        <coding_rule class="SA_LOCAL_SELF_COMPARISON" level="CRITICAL" enabled="true" />
+        <coding_rule class="SA_LOCAL_SELF_COMPUTATION" level="CRITICAL" enabled="true" />
+        <coding_rule class="SBSC_USE_STRINGBUFFER_CONCATENATION" level="CRITICAL" enabled="true" />
+        <coding_rule class="SC_START_IN_CTOR" level="CRITICAL" enabled="true" />
+        <coding_rule class="SE_BAD_FIELD" level="MINOR" enabled="false" />
+        <coding_rule class="SE_BAD_FIELD_INNER_CLASS" level="MINOR" enabled="true" />
+        <coding_rule class="SE_BAD_FIELD_STORE" level="CRITICAL" enabled="true" />
+        <coding_rule class="SE_COMPARATOR_SHOULD_BE_SERIALIZABLE" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_INNER_CLASS" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_METHOD_MUST_BE_PRIVATE" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_NONFINAL_SERIALVERSIONID" level="CRITICAL" enabled="true" />
+        <coding_rule class="SE_NONLONG_SERIALVERSIONID" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_NONSTATIC_SERIALVERSIONID" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_NO_SERIALVERSIONID" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_NO_SUITABLE_CONSTRUCTOR" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_NO_SUITABLE_CONSTRUCTOR_FOR_EXTERNALIZATION" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_PRIVATE_READ_RESOLVE_NOT_INHERITED" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_READ_RESOLVE_IS_STATIC" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_READ_RESOLVE_MUST_RETURN_OBJECT" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_TRANSIENT_FIELD_NOT_RESTORED" level="MAJOR" enabled="true" />
+        <coding_rule class="SE_TRANSIENT_FIELD_OF_NONSERIALIZABLE_CLASS" level="MAJOR" enabled="true" />
+        <coding_rule class="SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH" level="MAJOR" enabled="false" />
+        <coding_rule class="SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH_TO_THROW" level="MAJOR" enabled="false" />
+        <coding_rule class="SF_SWITCH_FALLTHROUGH" level="MAJOR" enabled="false" />
+        <coding_rule class="SF_SWITCH_NO_DEFAULT" level="MAJOR" enabled="false" />
+        <coding_rule class="SIC_INNER_SHOULD_BE_STATIC" level="MAJOR" enabled="true" />
+        <coding_rule class="SIC_INNER_SHOULD_BE_STATIC_ANON" level="MAJOR" enabled="true" />
+        <coding_rule class="SIC_INNER_SHOULD_BE_STATIC_NEEDS_THIS" level="MAJOR" enabled="true" />
+        <coding_rule class="SIC_THREADLOCAL_DEADLY_EMBRACE" level="MAJOR" enabled="false" />
+        <coding_rule class="SIO_SUPERFLUOUS_INSTANCEOF" level="CRITICAL" enabled="true" />
+        <coding_rule class="SI_INSTANCE_BEFORE_FINALS_ASSIGNED" level="CRITICAL" enabled="true" />
+        <coding_rule class="SP_SPIN_ON_FIELD" level="MAJOR" enabled="true" />
+        <coding_rule class="SQL_BAD_PREPARED_STATEMENT_ACCESS" level="CRITICAL" enabled="true" />
+        <coding_rule class="SQL_BAD_RESULTSET_ACCESS" level="CRITICAL" enabled="true" />
+        <coding_rule class="SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE" level="CRITICAL" enabled="true" />
+        <coding_rule class="SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING" level="CRITICAL" enabled="true" />
+        <coding_rule class="SR_NOT_CHECKED" level="MAJOR" enabled="true" />
+        <coding_rule class="SS_SHOULD_BE_STATIC" level="MAJOR" enabled="true" />
+        <coding_rule class="STCAL_INVOKE_ON_STATIC_CALENDAR_INSTANCE" level="CRITICAL" enabled="true" />
+        <coding_rule class="STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE" level="CRITICAL" enabled="true" />
+        <coding_rule class="STCAL_STATIC_CALENDAR_INSTANCE" level="CRITICAL" enabled="true" />
+        <coding_rule class="STCAL_STATIC_SIMPLE_DATE_FORMAT_INSTANCE" level="CRITICAL" enabled="true" />
+        <coding_rule class="STI_INTERRUPTED_ON_CURRENTTHREAD" level="CRITICAL" enabled="true" />
+        <coding_rule class="STI_INTERRUPTED_ON_UNKNOWNTHREAD" level="CRITICAL" enabled="true" />
+        <coding_rule class="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD" level="CRITICAL" enabled="true" />
+        <coding_rule class="SWL_SLEEP_WITH_LOCK_HELD" level="CRITICAL" enabled="true" />
+        <coding_rule class="SW_SWING_METHODS_INVOKED_IN_SWING_THREAD" level="MAJOR" enabled="true" />
+        <coding_rule class="TLW_TWO_LOCK_WAIT" level="MAJOR" enabled="true" />
+        <coding_rule class="TQ_ALWAYS_VALUE_USED_WHERE_NEVER_REQUIRED" level="CRITICAL" enabled="true" />
+        <coding_rule class="TQ_COMPARING_VALUES_WITH_INCOMPATIBLE_TYPE_QUALIFIERS" level="CRITICAL" enabled="false" />
+        <coding_rule class="TQ_EXPLICIT_UNKNOWN_SOURCE_VALUE_REACHES_ALWAYS_SINK" level="CRITICAL" enabled="true" />
+        <coding_rule class="TQ_EXPLICIT_UNKNOWN_SOURCE_VALUE_REACHES_NEVER_SINK" level="CRITICAL" enabled="true" />
+        <coding_rule class="TQ_MAYBE_SOURCE_VALUE_REACHES_ALWAYS_SINK" level="CRITICAL" enabled="true" />
+        <coding_rule class="TQ_MAYBE_SOURCE_VALUE_REACHES_NEVER_SINK" level="CRITICAL" enabled="true" />
+        <coding_rule class="TQ_NEVER_VALUE_USED_WHERE_ALWAYS_REQUIRED" level="CRITICAL" enabled="true" />
+        <coding_rule class="TQ_UNKNOWN_VALUE_USED_WHERE_ALWAYS_STRICTLY_REQUIRED" level="CRITICAL" enabled="false" />
+        <coding_rule class="UCF_USELESS_CONTROL_FLOW" level="CRITICAL" enabled="true" />
+        <coding_rule class="UCF_USELESS_CONTROL_FLOW_NEXT_LINE" level="CRITICAL" enabled="true" />
+        <coding_rule class="UC_USELESS_CONDITION" level="MAJOR" enabled="false" />
+        <coding_rule class="UC_USELESS_CONDITION_TYPE" level="MAJOR" enabled="false" />
+        <coding_rule class="UC_USELESS_OBJECT" level="MAJOR" enabled="false" />
+        <coding_rule class="UC_USELESS_OBJECT_STACK" level="MAJOR" enabled="false" />
+        <coding_rule class="UC_USELESS_VOID_METHOD" level="MAJOR" enabled="false" />
+        <coding_rule class="UG_SYNC_SET_UNSYNC_GET" level="MAJOR" enabled="true" />
+        <coding_rule class="UI_INHERITANCE_UNSAFE_GETRESOURCE" level="MAJOR" enabled="true" />
+        <coding_rule class="UL_UNRELEASED_LOCK" level="CRITICAL" enabled="true" />
+        <coding_rule class="UL_UNRELEASED_LOCK_EXCEPTION_PATH" level="CRITICAL" enabled="true" />
+        <coding_rule class="UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS" level="CRITICAL" enabled="true" />
+        <coding_rule class="UM_UNNECESSARY_MATH" level="CRITICAL" enabled="true" />
+        <coding_rule class="UPM_UNCALLED_PRIVATE_METHOD" level="CRITICAL" enabled="true" />
+        <coding_rule class="URF_UNREAD_FIELD" level="MAJOR" enabled="true" />
+        <coding_rule class="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" level="CRITICAL" enabled="false" />
+        <coding_rule class="UR_UNINIT_READ" level="MAJOR" enabled="true" />
+        <coding_rule class="UR_UNINIT_READ_CALLED_FROM_SUPER_CONSTRUCTOR" level="MAJOR" enabled="false" />
+        <coding_rule class="USM_USELESS_ABSTRACT_METHOD" level="MAJOR" enabled="false" />
+        <coding_rule class="USM_USELESS_SUBCLASS_METHOD" level="MAJOR" enabled="false" />
+        <coding_rule class="UUF_UNUSED_FIELD" level="MAJOR" enabled="true" />
+        <coding_rule class="UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD" level="CRITICAL" enabled="false" />
+        <coding_rule class="UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" level="MAJOR" enabled="false" />
+        <coding_rule class="UWF_NULL_FIELD" level="CRITICAL" enabled="true" />
+        <coding_rule class="UWF_UNWRITTEN_FIELD" level="MAJOR" enabled="false" />
+        <coding_rule class="UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD" level="CRITICAL" enabled="false" />
+        <coding_rule class="UW_UNCOND_WAIT" level="MAJOR" enabled="true" />
+        <coding_rule class="VA_FORMAT_STRING_BAD_ARGUMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="VA_FORMAT_STRING_BAD_CONVERSION" level="CRITICAL" enabled="true" />
+        <coding_rule class="VA_FORMAT_STRING_BAD_CONVERSION_FROM_ARRAY" level="MAJOR" enabled="true" />
+        <coding_rule class="VA_FORMAT_STRING_BAD_CONVERSION_TO_BOOLEAN" level="MAJOR" enabled="true" />
+        <coding_rule class="VA_FORMAT_STRING_EXPECTED_MESSAGE_FORMAT_SUPPLIED" level="MAJOR" enabled="false" />
+        <coding_rule class="VA_FORMAT_STRING_EXTRA_ARGUMENTS_PASSED" level="MAJOR" enabled="true" />
+        <coding_rule class="VA_FORMAT_STRING_ILLEGAL" level="CRITICAL" enabled="true" />
+        <coding_rule class="VA_FORMAT_STRING_MISSING_ARGUMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="VA_FORMAT_STRING_NO_PREVIOUS_ARGUMENT" level="CRITICAL" enabled="true" />
+        <coding_rule class="VA_FORMAT_STRING_USES_NEWLINE" level="CRITICAL" enabled="false" />
+        <coding_rule class="VA_PRIMITIVE_ARRAY_PASSED_TO_OBJECT_VARARG" level="CRITICAL" enabled="true" />
+        <coding_rule class="VO_VOLATILE_INCREMENT" level="CRITICAL" enabled="false" />
+        <coding_rule class="VO_VOLATILE_REFERENCE_TO_ARRAY" level="MAJOR" enabled="true" />
+        <coding_rule class="VR_UNRESOLVABLE_REFERENCE" level="MAJOR" enabled="false" />
+        <coding_rule class="WA_AWAIT_NOT_IN_LOOP" level="CRITICAL" enabled="true" />
+        <coding_rule class="WA_NOT_IN_LOOP" level="CRITICAL" enabled="true" />
+        <coding_rule class="WL_USING_GETCLASS_RATHER_THAN_CLASS_LITERAL" level="CRITICAL" enabled="true" />
+        <coding_rule class="WMI_WRONG_MAP_ITERATOR" level="CRITICAL" enabled="true" />
+        <coding_rule class="WS_WRITEOBJECT_SYNC" level="CRITICAL" enabled="true" />
+        <coding_rule class="XFB_XML_FACTORY_BYPASS" level="CRITICAL" enabled="true" />
+        <coding_rule class="XSS_REQUEST_PARAMETER_TO_JSP_WRITER" level="CRITICAL" enabled="true" />
+        <coding_rule class="XSS_REQUEST_PARAMETER_TO_SEND_ERROR" level="CRITICAL" enabled="true" />
+        <coding_rule class="XSS_REQUEST_PARAMETER_TO_SERVLET_WRITER" level="CRITICAL" enabled="true" />
+      </profile>
+    </profiles>
+    <list size="0" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644 (file)
index 0000000..7f68460
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RunConfigurationProducerService">
+    <option name="ignoredProducers">
+      <set>
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
+      </set>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644 (file)
index 0000000..42afabf
--- /dev/null
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/EQC_G5.jks b/app/EQC_G5.jks
new file mode 100644 (file)
index 0000000..2229d46
Binary files /dev/null and b/app/EQC_G5.jks differ
diff --git a/app/IcA9Launcher/release/IcA9Launcher_V1_5.0_202008171714_release.apk b/app/IcA9Launcher/release/IcA9Launcher_V1_5.0_202008171714_release.apk
new file mode 100644 (file)
index 0000000..387f58f
Binary files /dev/null and b/app/IcA9Launcher/release/IcA9Launcher_V1_5.0_202008171714_release.apk differ
diff --git a/app/IcA9Launcher/release/output-metadata.json b/app/IcA9Launcher/release/output-metadata.json
new file mode 100644 (file)
index 0000000..6a30b8a
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "version": 1,
+  "artifactType": {
+    "type": "APK",
+    "kind": "Directory"
+  },
+  "applicationId": "com.ic.ak.launcher",
+  "variantName": "IcA9LauncherRelease",
+  "elements": [
+    {
+      "type": "SINGLE",
+      "filters": [],
+      "properties": [],
+      "versionCode": 1,
+      "versionName": "5.0",
+      "enabled": true,
+      "outputFile": "IcA9Launcher_V1_5.0_202008171714_release.apk"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/app/IcAkLauncher/release/IcAkLauncher_V1_3.0_202008072245_release.apk b/app/IcAkLauncher/release/IcAkLauncher_V1_3.0_202008072245_release.apk
new file mode 100644 (file)
index 0000000..49e8898
Binary files /dev/null and b/app/IcAkLauncher/release/IcAkLauncher_V1_3.0_202008072245_release.apk differ
diff --git a/app/IcAkLauncher/release/output-metadata.json b/app/IcAkLauncher/release/output-metadata.json
new file mode 100644 (file)
index 0000000..efeab5b
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "version": 1,
+  "artifactType": {
+    "type": "APK",
+    "kind": "Directory"
+  },
+  "applicationId": "com.ic.ak.launcher",
+  "variantName": "IcAkLauncherRelease",
+  "elements": [
+    {
+      "type": "SINGLE",
+      "filters": [],
+      "properties": [],
+      "versionCode": 1,
+      "versionName": "3.0",
+      "enabled": true,
+      "outputFile": "IcAkLauncher_V1_3.0_202008072245_release.apk"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644 (file)
index 0000000..69ae875
--- /dev/null
@@ -0,0 +1,131 @@
+apply plugin: 'com.android.application'
+
+android {
+
+    compileSdkVersion 29
+
+    defaultConfig {
+        applicationId "com.ic.ak.launcher"
+        minSdkVersion 19
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+    }
+
+    buildFeatures {
+        dataBinding = true
+    }
+
+    //使用JDK1.8
+    compileOptions {
+        targetCompatibility JavaVersion.VERSION_1_8
+        sourceCompatibility JavaVersion.VERSION_1_8
+    }
+
+    signingConfigs {
+        key {
+            storeFile file("EQC_G5.jks")
+            storePassword "123456"
+            keyAlias "watch_g5"
+            keyPassword "123456"
+        }
+    }
+
+    sourceSets {
+        main {
+            jni.srcDirs = []
+            manifest.srcFile 'src/main/AndroidManifest.xml'
+            java.srcDirs = ['src/main/java', 'src/main/aidl']
+            resources.srcDirs = ['src/main/java', 'src/main/aidl']
+            aidl.srcDirs = ['src/main/aidl']
+            res.srcDirs = ['src/main/res']
+            assets.srcDirs = ['src/main/assets']
+        }
+    }
+
+    productFlavors{
+
+        IcA9Launcher{
+            flavorDimensions "IcA9Launcher"
+            versionCode 1
+            versionName "5.0"
+            buildConfigField "int", "productType", "1002"
+
+        }
+
+        IcAkLauncher{
+            flavorDimensions "IcAkLauncher"
+            versionCode 1
+            versionName "5.0"
+            buildConfigField "int", "productType", "1001"
+        }
+    }
+
+    buildTypes {
+        release {
+            zipAlignEnabled true     // zip 对齐优化
+            shrinkResources true       // 移除未使用的资源文件
+            signingConfig signingConfigs.key
+            minifyEnabled true
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+            renderscriptDebuggable = false
+            debuggable = false
+            jniDebuggable = false
+            manifestPlaceholders = [:]
+        }
+
+        debug {
+            signingConfig signingConfigs.key
+        }
+    }
+
+    android.applicationVariants.all { variant ->
+        variant.outputs.all {
+            if (variant.buildType.name == "release") {
+                outputFileName = "${variant.getFlavorName()}_V${versionCode}_${versionName}_${releaseTime()}_release.apk"
+            } else {
+                outputFileName = "${variant.getFlavorName()}_V${versionCode}_${versionName}_${releaseTime()}_debug.apk"
+            }
+        }
+    }
+}
+
+static def releaseTime() {
+    return new Date().format("yyyyMMddHHmm", TimeZone.getTimeZone("GMT+08:00"))
+}
+
+dependencies {
+    implementation fileTree(dir: "libs", include: ["*.jar"])
+    implementation 'androidx.appcompat:appcompat:1.1.0'
+    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+
+    // ViewModel
+    implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"
+    // LiveData
+    implementation "androidx.lifecycle:lifecycle-livedata:2.2.0"
+    // Saved state module for ViewModel
+    implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0"
+    // alternately - if using Java8, use the following instead of lifecycle-compiler
+    implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
+    // optional - ReactiveStreams support for LiveData
+    implementation "androidx.lifecycle:lifecycle-reactivestreams:2.2.0"
+
+    implementation "androidx.viewpager2:viewpager2:1.0.0"
+    implementation 'com.jakewharton.threetenabp:threetenabp:1.2.2'
+
+    implementation 'com.jakewharton:butterknife:10.2.1'
+    annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
+
+    implementation 'com.github.bumptech.glide:glide:4.11.0'
+    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
+
+    implementation 'org.greenrobot:eventbus:3.2.0'
+
+    implementation 'com.xhinliang:LunarCalendar:4.0.7'
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644 (file)
index 0000000..2fcfd84
--- /dev/null
@@ -0,0 +1,155 @@
+# 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
+-dontoptimize                           # 混合时不使用大小写混合,混合后的类名为小写
+-dontusemixedcaseclassnames             # 混合时不使用大小写混合,混合后的类名为小写
+-dontskipnonpubliclibraryclasses        # 不跳过library中的非public的类
+-dontskipnonpubliclibraryclassmembers   # 不跳过library中的非public的类成员
+-dontpreverify                          # 不做预校验,preverify是proguard的四个步骤之一,Android平台不需要preverify,去掉这一步能够加快混淆速度
+-verbose                                # 在处理时打印冗长的信息
+
+# 保留异常表,以便编译器知道哪些异常可能被抛出
+# 保留InnerClasses,否则外部无法引用内部类
+# 保留Signature,否则无法访问泛型
+-keepattributes Exceptions,SourceFile,LineNumberTable,EnclosingMethod,Signature,*Annotation*,InnerClasses,Deprecated
+
+################################## 需要保留的公共部分 ##################################
+# 保留四大组件,自定义的Application等等这些类不被混淆
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class * extends android.view.View
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keep class android.support.** { *; }
+-keep public class * extends android.support.v4.**
+-keep public class * extends android.support.v7.**
+-keep public class * extends android.support.annotation.**
+-keep public class * extends android.app.Fragment
+-keep class com.google.** { *; }
+
+# 保留R下面的资源
+-keep class **.R$* {*;}
+-keepclassmembers class **.R$* {
+    public static <fields>;
+}
+
+# 保留本地native方法不被混淆
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+# 保留在Activity中的方法参数是view的方法,
+# 这样以来我们在layout中写的onClick就不会被影响
+-keepclassmembers class * extends android.app.Activity{
+    public void *(android.view.View);
+}
+
+# 保留我们自定义控件(继承自View)不被混淆
+-keep public class * extends android.view.View{
+    *** get*();
+    void set*(***);
+    public <init>(android.content.Context);
+    public <init>(android.content.Context, android.util.AttributeSet);
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclasseswithmembernames class * {
+    public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembernames class * {
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+# 保留枚举类不被混淆
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+# 保留Parcelable序列化类不被混淆
+-keep class * implements android.os.Parcelable {
+  public static final android.os.Parcelable$Creator *;
+}
+
+# 保留Serializable序列化的类不被混淆
+-keepclassmembers class * implements java.io.Serializable {
+    static final long serialVersionUID;
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+    !static !transient <fields>;
+    !private <fields>;
+    !private <methods>;
+    private void writeObject(java.io.ObjectOutputStream);
+    private void readObject(java.io.ObjectInputStream);
+    java.lang.Object writeReplace();
+    java.lang.Object readResolve();
+}
+
+# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
+-keepclassmembers class * {
+    void *(**On*Event);
+    void *(**On*Listener);
+}
+
+
+-keep class com.sun.jna.** { *; }
+-dontwarn com.sun.jna.**
+
+-keep public class com.android.support.a
+-keep public class com.android.support.b
+-keep public class rx.internal.util
+
+#androidx 混淆
+-keep class com.google.android.material.** {*;}
+-keep class androidx.** {*;}
+-keep public class * extends androidx.**
+-keep interface androidx.** {*;}
+-dontwarn com.google.android.material.**
+-dontnote com.google.android.material.**
+-dontwarn androidx.**
+
+-keepattributes *Annotation*
+-keepclassmembers class * {
+    @org.greenrobot.eventbus.Subscribe <methods>;
+}
+-keep enum org.greenrobot.eventbus.ThreadMode { *; }
+
+# And if you use AsyncExecutor:
+-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
+    <init>(java.lang.Throwable);
+}
+
+-keep public class * implements com.bumptech.glide.module.GlideModule
+-keep class * extends com.bumptech.glide.module.AppGlideModule {
+ <init>(...);
+}
+-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
+  **[] $VALUES;
+  public *;
+}
+-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
+  *** rewind();
+}
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/ic/ak/launcher/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/ic/ak/launcher/ExampleInstrumentedTest.java
new file mode 100644 (file)
index 0000000..9907abb
--- /dev/null
@@ -0,0 +1,26 @@
+package com.ic.ak.launcher;
+
+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 <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        assertEquals("com.ic.ak.launcher", appContext.getPackageName());
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..decdb91
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.ic.ak.launcher"
+    android:sharedUserId="android.uid.system">
+
+    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.CALL_PHONE" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+    <application
+        android:name=".LauncherApp"
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <activity android:name=".ui.DialogActivity"
+            android:theme="@style/DialogActivityStyle"
+            android:launchMode="singleInstance"/>
+        <activity android:name=".ui.notification.NotificationActivity" />
+        <activity
+            android:name=".ui.MainActivity"
+            android:configChanges="keyboardHidden|orientation|screenSize|locale|screenLayout|mcc|mnc|layoutDirection">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.intent.action.VIEW" />
+
+                <category android:name="android.intent.category.HOME" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.MONKEY" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/app/src/main/java/com/ic/ak/launcher/LauncherApp.java b/app/src/main/java/com/ic/ak/launcher/LauncherApp.java
new file mode 100644 (file)
index 0000000..bc7c011
--- /dev/null
@@ -0,0 +1,79 @@
+package com.ic.ak.launcher;
+
+import android.app.Application;
+import android.content.Context;
+import android.os.PowerManager;
+import android.telephony.TelephonyManager;
+
+import com.ic.ak.launcher.data.app.AppDispose;
+import com.ic.ak.launcher.data.battery.BatteryDispose;
+import com.ic.ak.launcher.data.hardware.HardwareDispose;
+import com.ic.ak.launcher.data.phone.PhoneDispose;
+import com.ic.ak.launcher.data.time.TimeDispose;
+import com.ic.ak.launcher.util.CrashHandler;
+import com.ic.ak.launcher.util.IcLog;
+import com.jakewharton.threetenabp.AndroidThreeTen;
+
+
+public class LauncherApp extends Application {
+
+    private AppDispose appDispose;
+    private BatteryDispose batteryDispose;
+    private PhoneDispose phoneDispose;
+    private TimeDispose timeDispose;
+    private HardwareDispose hardwareDispose;
+
+    private TelephonyManager mTelephony;
+
+    private PowerManager powerManager;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        CrashHandler crashHandler = CrashHandler.getInstance();
+        crashHandler.init(getApplicationContext());
+
+        AndroidThreeTen.init(this);
+        IcLog.setLogHead("IcAk");
+
+        appDispose = new AppDispose();
+        batteryDispose = new BatteryDispose();
+        phoneDispose = new PhoneDispose(this);
+        timeDispose = new TimeDispose();
+        hardwareDispose = new HardwareDispose();
+    }
+
+    public TelephonyManager getApplicationTelephony() {
+        if (mTelephony == null) {
+            mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+        }
+        return mTelephony;
+    }
+
+    public boolean getScreenState() {
+        if (powerManager == null) {
+            powerManager = (PowerManager) getSystemService(POWER_SERVICE);
+        }
+        return powerManager.isScreenOn();
+    }
+
+    public AppDispose getAppDispose() {
+        return appDispose;
+    }
+
+    public BatteryDispose getBatteryDispose() {
+        return batteryDispose;
+    }
+
+    public PhoneDispose getPhoneDispose() {
+        return phoneDispose;
+    }
+
+    public TimeDispose getTimeDispose() {
+        return timeDispose;
+    }
+
+    public HardwareDispose getHardwareDispose() {
+        return hardwareDispose;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/app/AppConfig.java b/app/src/main/java/com/ic/ak/launcher/data/app/AppConfig.java
new file mode 100644 (file)
index 0000000..4334891
--- /dev/null
@@ -0,0 +1,92 @@
+package com.ic.ak.launcher.data.app;
+
+import com.ic.ak.launcher.BuildConfig;
+import com.ic.ak.launcher.R;
+
+final public class AppConfig {
+
+    public static AppItem[] getCurrentSystemAppListConfig() {
+        int product = BuildConfig.productType;
+        switch (product){
+            case 1001:
+                return AK_APP_LIST;
+            case 1002:
+                return A9_APP_LIST;
+            default:
+                return AK_APP_LIST;
+        }
+    }
+
+    private final static AppItem[] AK_APP_LIST = new AppItem[]{
+            new AppItem(R.string.app_title_living_home, R.mipmap.ak_app_icon_hotline,3,
+                    null, null,
+                    null, null),
+            new AppItem(R.string.app_title_dial, R.mipmap.ak_app_icon_dial,4,
+                    null, null,
+                    "com.ic.dial", "com.ic.dial.MainActivity"),
+            new AppItem(R.string.app_title_call_records, R.mipmap.ak_app_icon_call_records,15,
+                    null, null,
+                    "com.yjsoft.phonelog", "com.yjsoft.phonelog.MainActivity"),
+            new AppItem(R.string.app_title_message, R.mipmap.ak_app_icon_message,5,
+                    null, null,
+                    "com.ic.message", "com.ic.message.MainActivity"),
+            new AppItem(R.string.app_title_pedometer, R.mipmap.ak_app_icon_walk,6,
+                    null, null,
+                    "com.ic.ak.hardware", "com.ic.ak.hardware.ui.PedometerActivity"),
+            new AppItem(R.string.app_title_health, R.mipmap.ak_app_icon_healthy,7,
+                    null, null,
+                    "com.ic.ak.hardware", "com.ic.ak.hardware.ui.BloodActivity"),
+            new AppItem(R.string.app_title_sleep, R.mipmap.ak_app_icon_sleep,8,
+                    null, null,
+                    "com.ic.ak.hardware", "com.ic.ak.hardware.ui.SleepActivity"),
+            new AppItem(R.string.app_title_sedentary, R.mipmap.ak_app_icon_sedentary,9,
+                    null, null,
+                    "com.ic.ak.hardware", "com.ic.ak.hardware.ui.SedentaryActivity"),
+            new AppItem(R.string.app_title_camera, R.mipmap.ak_app_icon_camera,10,
+                    null, null,
+                    "com.eqc.camera", "com.eqc.camera.TakePictureActivity"),
+            new AppItem(R.string.app_title_album, R.mipmap.ak_app_icon_album,11,
+                    null, null,
+                    "com.eqc.gallery", "com.eqc.gallery.ui.LocalAlbumDetail"),
+            /**new AppItem(R.string.app_title_alipay, R.mipmap.ak_app_icon_alipay,12,
+                    null, null,
+                    "com.eg.android.AlipayGphone", "com.alipay.watch.ui.MainActivity"),**/
+            new AppItem(R.string.app_title_app_bind, R.mipmap.ak_app_icon_app_bind,13,
+                    null, null,
+                    "com.ic.ak.hardware", "com.ic.ak.hardware.ui.AppBindActivity"),
+            new AppItem(R.string.app_title_setting, R.mipmap.ak_app_icon_setting,14,
+                    null, null,
+                    "com.ic.setting", "com.ic.setting.MainActivity")
+    };
+
+    private final static AppItem[] A9_APP_LIST = new AppItem[]{
+        /**    new AppItem(R.string.a9_app_title_message, R.mipmap.a9_app_icon_message,-1,
+                    null, null,
+                    "com.ic.message", "com.ic.message.MainActivity"),
+        */
+            new AppItem(R.string.a9_app_title_health, R.mipmap.a9_app_icon_healthy,-1,
+                    null, null,
+                    "com.ic.ak.hardware", "com.ic.ak.hardware.ui.a9.BloodA9Activity"),
+            new AppItem(R.string.a9_app_title_temperature, R.mipmap.a9_app_icon_temp,-1,
+                    null, null,
+                    "com.ic.ak.hardware", "com.ic.ak.hardware.ui.a9.TemperatureA9Activity"),
+            new AppItem(R.string.a9_app_title_camera, R.mipmap.a9_app_icon_camera,-1,
+                    null, null,
+                    "com.ic.camera", "com.ic.camera.MainActivity"),
+            new AppItem(R.string.a9_app_title_album, R.mipmap.a9_app_icon_album,-1,
+                    null, null,
+                    "com.ic.album", "com.ic.album.MainActivity"),
+            new AppItem(R.string.a9_app_title_pedometer, R.mipmap.a9_app_icon_walk,-1,
+                    null, null,
+                    "com.ic.ak.hardware", "com.ic.ak.hardware.ui.a9.PedometerA9Activity"),
+            /**new AppItem(R.string.a9_app_title_contacts, R.mipmap.a9_app_icon_contacts,-1,
+                    null, null,
+                    "com.enqualcomm.imessage", "com.enqualcomm.imessage.ui.PhoneDirectoryActivity"),
+            new AppItem(R.string.a9_app_title_dial, R.mipmap.a9_app_icon_dial,
+                    null, null,
+                    "com.ic.dial", "com.ic.dial.MainActivity"),**/
+            new AppItem(R.string.a9_app_title_setting, R.mipmap.a9_app_icon_setting,-1,
+                    null, null,
+                    "com.ic.setting", "com.ic.setting.MainActivity")
+    };
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/app/AppDispose.java b/app/src/main/java/com/ic/ak/launcher/data/app/AppDispose.java
new file mode 100644 (file)
index 0000000..d63603d
--- /dev/null
@@ -0,0 +1,98 @@
+package com.ic.ak.launcher.data.app;
+
+import androidx.fragment.app.Fragment;
+
+import com.ic.ak.launcher.BuildConfig;
+import com.ic.ak.launcher.ui.fragment.AppFragment;
+import com.ic.ak.launcher.ui.fragment.MainA9Fragment;
+import com.ic.ak.launcher.ui.fragment.MainFragment;
+import com.ic.ak.launcher.util.IcLog;
+
+import java.util.Arrays;
+
+public class AppDispose {
+
+    private static final int SIZE = Integer.MAX_VALUE;
+    private int mCenterPosition;
+    private int mMainPosition;
+    private boolean[] mIndicatorState;
+
+
+    public AppDispose() {
+        mCenterPosition = SIZE / 2;
+        mMainPosition = mCenterPosition;
+        mIndicatorState = new boolean[AppConfig.getCurrentSystemAppListConfig().length];
+        Arrays.fill(mIndicatorState, false);
+    }
+
+    public int getViewPageAdapterSize() {
+        return SIZE;
+    }
+
+    public int getCenterPosition() {
+        return mCenterPosition;
+    }
+
+    public boolean[] getIndicatorStateArray() {
+        return mIndicatorState;
+    }
+
+    public int transformPositionIndicatorIndex(int position) {
+        if (position == mMainPosition) {
+            return -1;
+        }
+
+        int interval = position - mMainPosition;
+        if (interval > 0) {
+            if (interval > mIndicatorState.length) {
+                mMainPosition = position;
+                return -1;
+            } else {
+                return interval - 1;
+            }
+        } else {
+            interval = Math.abs(interval);
+            if (interval > mIndicatorState.length) {
+                mMainPosition = position;
+                return -1;
+            } else {
+                return mIndicatorState.length - interval;
+            }
+        }
+    }
+
+    public int getAppItemPlayItem(int position){
+        if (position == mMainPosition) {
+            return -1;
+        }
+
+        int index = transformPositionIndicatorIndex(position);
+        return AppConfig.getCurrentSystemAppListConfig()[index].getPlayVoiceIndex();
+    }
+
+    public Fragment getViewPageAdapterFragment(int position) {
+
+        if (position == mMainPosition) {
+            return getCurrentProductMainFragment();
+        }
+        int index = transformPositionIndicatorIndex(position);
+        if (index == -1) {
+            return getCurrentProductMainFragment();
+        }
+        AppItem item = AppConfig.getCurrentSystemAppListConfig()[index];
+
+        return AppFragment.newInstance(item);
+    }
+
+    private Fragment getCurrentProductMainFragment(){
+        int product = BuildConfig.productType;
+        switch (product){
+            case 1001:
+                return MainFragment.newInstance();
+            case 1002:
+                return MainA9Fragment.newInstance();
+            default:
+                return MainFragment.newInstance();
+        }
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/app/AppItem.java b/app/src/main/java/com/ic/ak/launcher/data/app/AppItem.java
new file mode 100644 (file)
index 0000000..7e2c31d
--- /dev/null
@@ -0,0 +1,133 @@
+package com.ic.ak.launcher.data.app;
+
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class AppItem implements Parcelable {
+    private int titleResId = 0;
+    private int iconResId = 0;
+    private int playVoiceIndex=0;
+    private String title = null;
+    private Drawable iconDrawable = null;
+    private String appPackage = null;
+    private String appMainClass = null;
+
+    public AppItem() {
+    }
+
+    public AppItem(int titleResId, int iconResId,int playVoiceIndex,
+                   String title, Drawable iconDrawable,
+                   String appPackage, String appMainClass) {
+        this.titleResId = titleResId;
+        this.iconResId = iconResId;
+        this.playVoiceIndex = playVoiceIndex;
+        this.title = title;
+        this.iconDrawable = iconDrawable;
+        this.appPackage = appPackage;
+        this.appMainClass = appMainClass;
+    }
+
+    public AppItem(Parcel p) {
+        this.titleResId = p.readInt();
+        this.iconResId = p.readInt();
+        this.playVoiceIndex = p.readInt();
+        this.title = p.readString();
+        // Deserialize Parcelable and cast to Bitmap first:
+        Bitmap bitmap = (Bitmap) p.readParcelable(getClass().getClassLoader());
+        // Convert Bitmap to Drawable:
+        iconDrawable = new BitmapDrawable(bitmap);
+
+        this.appPackage = p.readString();
+        this.appMainClass = p.readString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(titleResId);
+        dest.writeInt(iconResId);
+        dest.writeInt(playVoiceIndex);
+        dest.writeString(title);
+        if(iconDrawable != null){
+            Bitmap bitmap = (Bitmap) ((BitmapDrawable) iconDrawable).getBitmap();
+            // Serialize bitmap as Parcelable:
+            dest.writeParcelable(bitmap, flags);
+        }
+        dest.writeString(appPackage);
+        dest.writeString(appMainClass);
+    }
+
+    public static final Parcelable.Creator<AppItem> CREATOR
+            = new Parcelable.Creator<AppItem>() {
+        public AppItem createFromParcel(Parcel in) {
+            return new AppItem(in);
+        }
+
+        public AppItem[] newArray(int size) {
+            return new AppItem[size];
+        }
+    };
+
+    public int getTitleResId() {
+        return titleResId;
+    }
+
+    public void setTitleResId(int titleResId) {
+        this.titleResId = titleResId;
+    }
+
+    public int getIconResId() {
+        return iconResId;
+    }
+
+    public void setIconResId(int iconResId) {
+        this.iconResId = iconResId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public Drawable getIconDrawable() {
+        return iconDrawable;
+    }
+
+    public void setIconDrawable(Drawable iconDrawable) {
+        this.iconDrawable = iconDrawable;
+    }
+
+    public String getAppPackage() {
+        return appPackage;
+    }
+
+    public void setAppPackage(String appPackage) {
+        this.appPackage = appPackage;
+    }
+
+    public String getAppMainClass() {
+        return appMainClass;
+    }
+
+    public void setAppMainClass(String appMainClass) {
+        this.appMainClass = appMainClass;
+    }
+
+    public int getPlayVoiceIndex() {
+        return playVoiceIndex;
+    }
+
+    public void setPlayVoiceIndex(int playVoiceIndex) {
+        this.playVoiceIndex = playVoiceIndex;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/battery/BatteryConnectStateEvent.java b/app/src/main/java/com/ic/ak/launcher/data/battery/BatteryConnectStateEvent.java
new file mode 100644 (file)
index 0000000..7b21e70
--- /dev/null
@@ -0,0 +1,9 @@
+package com.ic.ak.launcher.data.battery;
+
+public class BatteryConnectStateEvent {
+    public boolean state;
+
+    public BatteryConnectStateEvent(boolean state) {
+        this.state = state;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/battery/BatteryDispose.java b/app/src/main/java/com/ic/ak/launcher/data/battery/BatteryDispose.java
new file mode 100644 (file)
index 0000000..ff390a5
--- /dev/null
@@ -0,0 +1,164 @@
+package com.ic.ak.launcher.data.battery;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.text.TextUtils;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MediatorLiveData;
+import androidx.lifecycle.MutableLiveData;
+
+import com.ic.ak.launcher.BuildConfig;
+import com.ic.ak.launcher.R;
+
+import org.greenrobot.eventbus.EventBus;
+
+
+public class BatteryDispose {
+
+    private static final String TAG = "BatteryDispose";
+
+    //信号图片
+    private static int[] AKBatteryResId = new int[]{
+            R.mipmap.ak_battery_0,
+            R.mipmap.ak_battery_1,
+            R.mipmap.ak_battery_2,
+            R.mipmap.ak_battery_3,
+            R.mipmap.ak_battery_4,
+            R.mipmap.ak_battery_5
+    };
+
+    private static int[] A9BatteryResId = new int[]{
+            R.mipmap.a9_battery_0,
+            R.mipmap.a9_battery_1,
+            R.mipmap.a9_battery_2,
+            R.mipmap.a9_battery_3,
+            R.mipmap.a9_battery_4,
+            R.mipmap.a9_battery_5
+    };
+
+    private MutableLiveData<String> mBatteryValueLiveData;
+    private MutableLiveData<Boolean> mBatteryChargingLiveData;
+    private MutableLiveData<Integer> mBatteryResIDLiveData;
+
+    public LiveData<Boolean> getBatteryChargingLiveData() {
+        return mBatteryChargingLiveData;
+    }
+
+    public LiveData<Integer> getBatteryResIDLiveData() {
+        return mBatteryResIDLiveData;
+    }
+
+    public MutableLiveData<String> getBatteryValueLiveData() {
+        return mBatteryValueLiveData;
+    }
+
+    public BatteryDispose() {
+        mBatteryValueLiveData = new MediatorLiveData<>();
+        mBatteryChargingLiveData = new MediatorLiveData<>();
+        mBatteryResIDLiveData = new MediatorLiveData<>();
+    }
+
+    public void registerBatteryReceiver(Context context) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+        filter.addAction(Intent.ACTION_POWER_CONNECTED);
+        filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
+        context.registerReceiver(mIntentReceiver, filter);
+    }
+
+    public void unRegisterBatteryReceiver(Context context) {
+        try {
+            context.unregisterReceiver(mIntentReceiver);
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent != null) {
+                String acyion = intent.getAction();
+
+                if (TextUtils.isEmpty(acyion)) {
+                    return;
+                }
+
+                switch (acyion) {
+                    case Intent.ACTION_BATTERY_CHANGED:
+                        int status = intent.getIntExtra("status", -1);
+                        int rawlevel = intent.getIntExtra("level", -1);
+                        int scale = intent.getIntExtra("scale", -1);
+                        updateBatteryValue(rawlevel, scale, status);
+                        break;
+                    case Intent.ACTION_POWER_DISCONNECTED:
+                        // 没有接电源
+                        mBatteryChargingLiveData.setValue(false);
+                        EventBus.getDefault().post(new BatteryConnectStateEvent(false));
+                        break;
+                    case Intent.ACTION_POWER_CONNECTED:
+                        //接电源
+                        EventBus.getDefault().post(new BatteryConnectStateEvent(true));
+                        break;
+                }
+            }
+        }
+    };
+
+    private void updateBatteryValue(int rawlevel, int scale, int status) {
+        int level = -1;
+        if (rawlevel >= 0 && scale > 0) {
+            level = (rawlevel * 100) / scale;
+        }
+
+        if (level == -1) return;
+
+        mBatteryValueLiveData.setValue(String.valueOf(rawlevel));
+
+        switch (status) {
+            case BatteryManager.BATTERY_STATUS_CHARGING:
+                mBatteryChargingLiveData.setValue(true);
+                break;
+            case BatteryManager.BATTERY_STATUS_FULL:
+                mBatteryChargingLiveData.setValue(false);
+                mBatteryResIDLiveData.setValue(getCurrentProductBatteryResId()[getBatteryLevel(level)]);
+                break;
+            default:
+                mBatteryResIDLiveData.setValue(getCurrentProductBatteryResId()[getBatteryLevel(level)]);
+                break;
+        }
+    }
+
+    private int getBatteryLevel(int level) {
+        int index = 0;
+        if (level > 85) {
+            index = 5;
+        } else if (level > 65) {
+            index = 4;
+        } else if (level > 40) {
+            index = 3;
+        } else if (level > 15) {
+            index = 2;
+        } else if (level > 7) {
+            index = 1;
+        }
+
+        return index;
+    }
+
+    public static int[] getCurrentProductBatteryResId(){
+        int product = BuildConfig.productType;
+        switch (product){
+            case 1001:
+                return AKBatteryResId;
+            case 1002:
+                return A9BatteryResId;
+            default:
+                return AKBatteryResId;
+        }
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/hardware/HardwareDispose.java b/app/src/main/java/com/ic/ak/launcher/data/hardware/HardwareDispose.java
new file mode 100644 (file)
index 0000000..65b08a4
--- /dev/null
@@ -0,0 +1,202 @@
+package com.ic.ak.launcher.data.hardware;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.text.TextUtils;
+
+import androidx.lifecycle.MediatorLiveData;
+import androidx.lifecycle.MutableLiveData;
+
+import com.ic.ak.launcher.BuildConfig;
+import com.ic.ak.launcher.ui.DialogActivity;
+import com.ic.ak.launcher.ui.MainActivity;
+import com.ic.ak.launcher.util.IcLog;
+
+import org.greenrobot.eventbus.EventBus;
+
+
+public class HardwareDispose {
+    private static final String TAG = "HardwareDispose";
+
+    private static final String HEART_ACTION = "com.ic.action.BLOOD_HEART";
+    private static final String PED_ACTION = "com.ic.action.PED_COUNT";
+
+    private static final String GET_PED_ACTION = "com.ic.action.GET_PED_COUNT";
+
+    private static final String TXT_ACTION = "action.ic.srvPushTxt";
+    private static final String TYPE_KEY = "msgType";
+    private static final String MSG_KEY = "txtMsg";
+
+    private static final String STRIP_ACTION = "com.ic.ACTION_STRIP";
+    private static final String EVENT_KEY = "eventID";
+
+    public static final String ACTION_BATTERYLOW = "com.ic.ACTION_BATTERYLOW";
+    public static final String KEY_BATTERY_EVENT = "eventID";
+
+    private static final String POWER_OFF_ACTION = "com.ic.action_IC_SHUTDOWN";
+    private static final String CLS_POWER = "com.ic.ak.hardware.ui.ShutDownActivity";
+
+    private static final String SOS_ACTION = "com.ic.action_IC_SOS";
+    private static final String CLS_SOS = "com.ic.ak.hardware.ui.sos.SosAkActivity";
+
+    public static final String ACTION_KEEPSIT_ALARM = "com.ic.action.keep_sit_alarm";
+
+    private MutableLiveData<String> mObsHardwareHeart;
+    private MutableLiveData<String> mObsHardwarePed;
+
+    public HardwareDispose() {
+        mObsHardwareHeart = new MediatorLiveData<>();
+        mObsHardwarePed = new MediatorLiveData<>();
+    }
+
+    public MutableLiveData<String> getObsHardwareHeart() {
+        return mObsHardwareHeart;
+    }
+
+    public MutableLiveData<String> getObsHardwarePed() {
+        return mObsHardwarePed;
+    }
+
+
+    public void sendGetPedBroadcast(Context context) {
+        Intent pedIntent = new Intent();
+        pedIntent.setAction(GET_PED_ACTION);
+        context.sendBroadcast(pedIntent);
+    }
+
+    public static void testBatteryBroadcast(Context context, String messgae) {
+        Intent intent = new Intent(TXT_ACTION);
+        intent.putExtra(TYPE_KEY,2);
+        intent.putExtra(MSG_KEY,messgae);
+        context.sendBroadcast(intent);
+    }
+
+    public void registerHardwareBroadcast(Context context) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(PED_ACTION);
+        filter.addAction(HEART_ACTION);
+        filter.addAction(POWER_OFF_ACTION);
+        filter.addAction(SOS_ACTION);
+        filter.addAction(TXT_ACTION);
+        int product = BuildConfig.productType;
+        if (product == 1001) {
+            filter.addAction(ACTION_KEEPSIT_ALARM);
+        }
+        if (product == 1002) {
+            filter.addAction(STRIP_ACTION);
+            filter.addAction(ACTION_BATTERYLOW);
+        }
+
+        context.registerReceiver(mIntentReceiver, filter);
+    }
+
+    public void unRegisterHardwareReceiver(Context context) {
+        try {
+            context.unregisterReceiver(mIntentReceiver);
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent != null) {
+                String acyion = intent.getAction();
+                if (TextUtils.isEmpty(acyion)) {
+                    return;
+                }
+                switch (acyion) {
+                    case PED_ACTION:
+                        int count = intent.getIntExtra("PED_COUNT", 0);
+                        mObsHardwarePed.setValue(String.valueOf(count));
+                        break;
+                    case HEART_ACTION:
+                        int heart = intent.getIntExtra("BLOOD_HEART", 0);
+                        mObsHardwareHeart.setValue(String.valueOf(heart));
+                        break;
+                    case STRIP_ACTION:
+                        int event = intent.getIntExtra(EVENT_KEY, -1);
+                        switch (event){
+                            case 0:
+                                //取消
+                                startDialogActivity(context,1005,"");
+                                break;
+                            case 1:
+                                //低点
+                                startDialogActivity(context,1006,"");
+                                break;
+                        }
+                        break;
+                    case ACTION_BATTERYLOW:
+                        int battery = intent.getIntExtra(KEY_BATTERY_EVENT, -1);
+                        switch (battery){
+                            case 0:
+                                //取消
+                                startDialogActivity(context,1003,"");
+                                break;
+                            case 1:
+                                //低点
+                                startDialogActivity(context,1004,"");
+                                break;
+                        }
+                        break;
+                    case TXT_ACTION:
+                        IcLog.i(TAG, "TXT ACTION");
+                        int type = intent.getIntExtra(TYPE_KEY, -1);
+                        String message = intent.getStringExtra(MSG_KEY);
+                        if (!TextUtils.isEmpty(message)) {
+                            switch (type){
+                                case 0:
+                                    startDialogActivity(context,1001,message);
+                                    break;
+                                case 1:
+                                    startDialogActivity(context,1000,message);
+                                    break;
+                                case 2:
+                                    startDialogActivity(context,1007,message);
+                                    break;
+                            }
+
+                        }
+                        break;
+                    case POWER_OFF_ACTION:
+                        IcLog.i(TAG, "power off");
+                        startHardwareActivity(context, CLS_POWER);
+                        break;
+                    case SOS_ACTION:
+                        IcLog.i(TAG, "sos");
+                        startHardwareActivity(context, CLS_SOS);
+                        break;
+                    case ACTION_KEEPSIT_ALARM:
+                        IcLog.i(TAG, "alarm");
+                        startDialogActivity(context,1002,"");
+                        break;
+                }
+            }
+        }
+    };
+
+
+    private void startHardwareActivity(Context context, String cls) {
+        try {
+            Intent intent = new Intent();
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setComponent(new ComponentName("com.ic.ak.hardware", cls));
+            context.startActivity(intent);
+        } catch (Exception e) {
+        }
+    }
+
+    private void startDialogActivity(Context context, int type, String message) {
+        Intent intent = new Intent();
+        intent.putExtra("TYPE", type);
+        intent.putExtra("MESSAGE", message);
+        intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+        intent.setComponent(new ComponentName("com.ic.ak.launcher", "com.ic.ak.launcher.ui.DialogActivity"));
+        context.startActivity(intent);
+    }
+
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/phone/CallPhone.java b/app/src/main/java/com/ic/ak/launcher/data/phone/CallPhone.java
new file mode 100644 (file)
index 0000000..1fda4cd
--- /dev/null
@@ -0,0 +1,50 @@
+package com.ic.ak.launcher.data.phone;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.ic.ak.launcher.LauncherApp;
+
+import static android.telephony.TelephonyManager.CALL_STATE_IDLE;
+
+public class CallPhone {
+
+    public void callPhone(LauncherApp mApp, String phone) {
+        Context context = mApp.getApplicationContext();
+        TelephonyManager manager =mApp.getApplicationTelephony();
+        if (manager.getCallState() != CALL_STATE_IDLE) {
+            return;
+        }
+
+        if (TextUtils.isEmpty(phone) || phone.length() <= 1) {
+            return;
+        }
+
+        if (!PhoneNumberUtils.isEmergencyNumber(phone)) {
+            if (!isHasSimCard(manager)) {
+                return;
+            }
+        }
+
+        Uri callUri = Uri.parse("tel://" + phone);
+        Intent callIntent = new Intent("android.intent.action.CALL_PRIVILEGED", callUri);
+        callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
+        context.startActivity(callIntent);
+    }
+
+    private boolean isHasSimCard(TelephonyManager manager) {
+        int simState = manager.getSimState();
+        boolean result = true;
+        switch (simState) {
+            case TelephonyManager.SIM_STATE_ABSENT:
+            case TelephonyManager.SIM_STATE_UNKNOWN:
+                result = false; // 没有SIM卡
+                break;
+        }
+        return result;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/phone/LoopThread.java b/app/src/main/java/com/ic/ak/launcher/data/phone/LoopThread.java
new file mode 100644 (file)
index 0000000..ff1448e
--- /dev/null
@@ -0,0 +1,54 @@
+package com.ic.ak.launcher.data.phone;
+
+import com.ic.ak.launcher.util.IcLog;
+
+public abstract class LoopThread implements Runnable {
+
+    private static final String TAG = "LoopThreadUtil";
+
+    private final Object lock = new Object();
+    private boolean pause = false;
+
+    protected abstract void onThreadExecute();
+
+    public void pauseQueryThread() {
+        pause = true;
+    }
+
+    public void resumeQueryThread() {
+        pause = false;
+        synchronized (lock) {
+            lock.notifyAll();
+        }
+    }
+
+    private void onPause() {
+        synchronized (lock) {
+            try {
+                IcLog.i(TAG, "Pause Loop Thread");
+                lock.wait();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Override
+    public void run() {
+        while (true) {
+            while (pause) {
+                onPause();
+            }
+
+            onThreadExecute();
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                //捕获到异常之后,执行break跳出循环
+                IcLog.i(TAG, "Stop Loop Thread");
+                break;
+            }
+        }
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/phone/PhoneDispose.java b/app/src/main/java/com/ic/ak/launcher/data/phone/PhoneDispose.java
new file mode 100644 (file)
index 0000000..582599b
--- /dev/null
@@ -0,0 +1,250 @@
+package com.ic.ak.launcher.data.phone;
+
+import android.app.Application;
+import android.net.TrafficStats;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.TelephonyManager;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+
+import com.ic.ak.launcher.BuildConfig;
+import com.ic.ak.launcher.LauncherApp;
+import com.ic.ak.launcher.R;
+
+import java.util.List;
+
+public class PhoneDispose extends LoopThread {
+
+    //L02 信号图片
+    private static int[] akSignalResId = new int[]{
+            R.mipmap.ak_signal_nosim,
+            R.mipmap.ak_signal_x,
+            R.mipmap.ak_signal_1,
+            R.mipmap.ak_signal_2,
+            R.mipmap.ak_signal_3,
+            R.mipmap.ak_signal_4
+    };
+
+    private static int[] a9SignalResId = new int[]{
+            R.mipmap.ak_signal_nosim,
+            R.mipmap.a9_signal_x,
+            R.mipmap.a9_signal_1,
+            R.mipmap.a9_signal_2,
+            R.mipmap.a9_signal_3,
+            R.mipmap.a9_signal_4
+    };
+
+    public static int[] akPhoneTypeResId = new int[]{
+            R.mipmap.ak_phone_type_2g,
+            R.mipmap.ak_phone_type_3g,
+            R.mipmap.ak_phone_type_4g,
+            R.mipmap.ak_phone_type_u
+    };
+
+    public static int[] a9PhoneTypeResId = new int[]{
+            R.mipmap.a9_phone_type_2g,
+            R.mipmap.a9_phone_type_3g,
+            R.mipmap.a9_phone_type_4g,
+            R.mipmap.a9_phone_type_u
+    };
+
+    //L02 信号图片
+    public static int[] akTransportResId = new int[]{
+            R.mipmap.ak_data_transport_0,
+            R.mipmap.ak_data_transport_1,
+            R.mipmap.ak_data_transport_2,
+            R.mipmap.ak_data_transport_3
+    };
+
+    private TelephonyManager mTelephony;
+    private Thread mThread;
+
+    private long receivedWork;
+    private long sendNetWork;
+
+    private boolean mOldSimCardState = false;
+    private boolean isFirst=true;
+    private int oldSignalLevel = -1;
+    private int oldTransportIndex=-1;
+
+    private MutableLiveData<Integer> mTypeID;
+    private MutableLiveData<Integer> mSignalID;
+    private MutableLiveData<Integer> mTransportID;
+    private MutableLiveData<Boolean> mSimCardState;
+
+
+    public PhoneDispose(Application application) {
+        mTelephony = ((LauncherApp) application).getApplicationTelephony();
+        mTypeID = new MutableLiveData<>();
+        mSignalID = new MutableLiveData<>();
+        mTransportID = new MutableLiveData<>();
+        mSimCardState = new MutableLiveData<>();
+
+        mThread = new Thread(this);
+        mThread.start();
+    }
+
+    @Override
+    protected void onThreadExecute() {
+        boolean state = querySimCardState(mTelephony);
+        if(state){
+            queryPhoneNetworkTypeResId(mTelephony);
+            getSignalStrength(mTelephony);
+            queryTrafficPollerValue();
+        }
+
+        if(state != mOldSimCardState || isFirst){
+            if(state){
+                mSignalID.postValue(getCurrentSignalResId()[5]);
+            }else{
+                mSignalID.postValue(getCurrentSignalResId()[0]);
+            }
+            mOldSimCardState = state;
+            mSimCardState.postValue(mOldSimCardState);
+            isFirst=false;
+        }
+    }
+
+    public LiveData<Integer> getTypeID() {
+        return mTypeID;
+    }
+
+    public LiveData<Integer> getSignalID() {
+        return mSignalID;
+    }
+
+    public LiveData<Integer> getTransportID() {
+        return mTransportID;
+    }
+
+    public LiveData<Boolean> getSimCardState() {
+        return mSimCardState;
+    }
+
+    public void stopLoopThread() {
+        if (mThread != null) {
+            mThread.interrupt();
+            mThread = null;
+        }
+    }
+
+    private void queryTrafficPollerValue() {
+        long rw = TrafficStats.getMobileRxPackets();
+        long sw = TrafficStats.getMobileTxPackets();
+        int index = 0;
+        if (rw > receivedWork && sw > sendNetWork) {
+            index = 3;
+        } else {
+            if (rw > receivedWork) {
+                index = 1;
+            }
+            if (sw > sendNetWork) {
+                index = 2;
+            }
+        }
+
+        receivedWork = rw;
+        sendNetWork = sw;
+
+        if (oldTransportIndex != index) {
+            mTransportID.postValue(akTransportResId[index]);
+            oldTransportIndex = index;
+        }
+    }
+
+    private void queryPhoneNetworkTypeResId(TelephonyManager tm) {
+        int networkType = tm.getNetworkType();
+        int[] resId = getCurrentPhoneTypeResId();
+        switch (networkType) {
+            case TelephonyManager.NETWORK_TYPE_GPRS:
+            case TelephonyManager.NETWORK_TYPE_EDGE:
+            case TelephonyManager.NETWORK_TYPE_CDMA:
+            case TelephonyManager.NETWORK_TYPE_1xRTT:
+            case TelephonyManager.NETWORK_TYPE_IDEN:
+                mTypeID.postValue(resId[0]);
+                return;
+            case TelephonyManager.NETWORK_TYPE_UMTS:
+            case TelephonyManager.NETWORK_TYPE_EVDO_0:
+            case TelephonyManager.NETWORK_TYPE_EVDO_A:
+            case TelephonyManager.NETWORK_TYPE_HSDPA:
+            case TelephonyManager.NETWORK_TYPE_HSUPA:
+            case TelephonyManager.NETWORK_TYPE_HSPA:
+            case TelephonyManager.NETWORK_TYPE_EVDO_B:
+            case TelephonyManager.NETWORK_TYPE_EHRPD:
+            case TelephonyManager.NETWORK_TYPE_HSPAP:
+                mTypeID.postValue(resId[1]);
+                return;
+            case TelephonyManager.NETWORK_TYPE_LTE:
+                mTypeID.postValue(resId[2]);
+                return;
+            default:
+                mTypeID.postValue(resId[3]);
+                return;
+        }
+    }
+
+    private boolean querySimCardState(TelephonyManager manager) {
+        if (manager == null) {
+            return false;
+        }
+        return manager.getSimState() == TelephonyManager.SIM_STATE_READY;
+    }
+
+    private void getSignalStrength(TelephonyManager manager) {
+        if (manager == null) {
+            return;
+        }
+
+        List<CellInfo> cellInfoList = manager.getAllCellInfo();
+        if (cellInfoList == null || cellInfoList.size() == 0) {
+            return;
+        }
+
+        int level = 1;
+
+        for (CellInfo cellInfo : cellInfoList) {
+            if (cellInfo instanceof CellInfoLte) {
+                level = ((CellInfoLte) cellInfo).getCellSignalStrength().getLevel() + 1;
+            } else if (cellInfo instanceof CellInfoCdma) {
+                level = ((CellInfoCdma) cellInfo).getCellSignalStrength().getLevel() + 1;
+            } else if (cellInfo instanceof CellInfoGsm) {
+                level = ((CellInfoGsm) cellInfo).getCellSignalStrength().getLevel() + 1;
+            } else if (cellInfo instanceof CellInfoWcdma) {
+                level = ((CellInfoWcdma) cellInfo).getCellSignalStrength().getLevel() + 1;
+            }
+        }
+
+        if (level != oldSignalLevel) {
+            oldSignalLevel = level;
+            mSignalID.postValue(getCurrentSignalResId()[level]);
+        }
+    }
+
+    public static int[] getCurrentSignalResId() {
+        int product = BuildConfig.productType;
+        switch (product){
+            case 1001:
+                return akSignalResId;
+            case 1002:
+                return a9SignalResId;
+        }
+
+        return akSignalResId;
+    }
+
+    public static int[] getCurrentPhoneTypeResId() {
+        int product = BuildConfig.productType;
+        switch (product){
+            case 1001:
+                return akPhoneTypeResId;
+            case 1002:
+                return a9PhoneTypeResId;
+        }
+        return akPhoneTypeResId;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/play/SoundPlayUtils.java b/app/src/main/java/com/ic/ak/launcher/data/play/SoundPlayUtils.java
new file mode 100644 (file)
index 0000000..356f493
--- /dev/null
@@ -0,0 +1,92 @@
+package com.ic.ak.launcher.data.play;
+
+import android.content.Context;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.SoundPool;
+import android.os.Build;
+
+import com.ic.ak.launcher.R;
+
+
+public class SoundPlayUtils {
+
+    private SoundPool mSoundPlayer;
+    private int[] soundID;
+    private int nowSoundIndex;
+
+    private SoundPool.OnLoadCompleteListener SoundLoadListener;
+
+    private static final int[] NUM_RAW = new int[]{
+            R.raw.chrg_connect,
+            R.raw.chrg_remove,
+            R.raw.chrg_complete,
+            R.raw.ak_app_voice_living_home,
+            R.raw.ak_app_voice_dial,
+            R.raw.ak_app_voice_message,
+            R.raw.ak_app_voice_ped,
+            R.raw.ak_app_voice_health,
+            R.raw.ak_app_voice_sleep,
+            R.raw.ak_app_voice_sedentary,
+            R.raw.ak_app_voice_camera,
+            R.raw.ak_app_voice_album,
+            R.raw.ak_app_voice_zfb,
+            R.raw.ak_app_voice_bind,
+            R.raw.ak_app_voice_setting,
+            R.raw.ak_app_voice_call_records,//15
+            R.raw.a9_antioff
+    };
+
+    public SoundPlayUtils() {
+        if (mSoundPlayer == null) {
+            if (Build.VERSION.SDK_INT > 21) {
+                SoundPool.Builder builder = new SoundPool.Builder();
+                //传入音频数量
+                builder.setMaxStreams(5);
+                //AudioAttributes是一个封装音频各种属性的方法
+                AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
+                //设置音频流的合适的属性
+                attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);//STREAM_MUSIC
+                //加载一个AudioAttributes
+                builder.setAudioAttributes(attrBuilder.build());
+                mSoundPlayer = builder.build();
+            } else {
+                mSoundPlayer = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
+            }
+        }
+        soundID = new int[NUM_RAW.length];
+    }
+
+    public void stopSoundPlay(int key){
+        if(mSoundPlayer != null){
+            mSoundPlayer.stop(soundID[key]);
+        }
+    }
+
+    public void releaseSoundPlayer() {
+        if (mSoundPlayer != null) {
+            mSoundPlayer.release();
+        }
+        mSoundPlayer = null;
+    }
+
+    public void playKeyboardSound(Context context, int key) {
+        nowSoundIndex = key;
+        int pID = soundID[key];
+
+        if (pID == 0) {
+            if (SoundLoadListener == null) {
+                SoundLoadListener = (soundPool, sampleId, status) -> SaveSoundPlayId(sampleId);
+                mSoundPlayer.setOnLoadCompleteListener(SoundLoadListener);
+            }
+            mSoundPlayer.load(context, NUM_RAW[key], 1);
+        } else {
+            mSoundPlayer.play(pID, 1, 1, 0, 0, 1);
+        }
+    }
+
+    private synchronized void SaveSoundPlayId(int sampleId) {
+        mSoundPlayer.play(sampleId, 1, 1, 1, 0, 1);
+        soundID[nowSoundIndex] = sampleId;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/data/time/TimeDispose.java b/app/src/main/java/com/ic/ak/launcher/data/time/TimeDispose.java
new file mode 100644 (file)
index 0000000..21bd408
--- /dev/null
@@ -0,0 +1,197 @@
+package com.ic.ak.launcher.data.time;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.text.TextUtils;
+import android.util.SparseArray;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MediatorLiveData;
+import androidx.lifecycle.MutableLiveData;
+
+import com.ic.ak.launcher.BuildConfig;
+import com.xhinliang.lunarcalendar.LunarCalendar;
+
+import org.threeten.bp.DayOfWeek;
+import org.threeten.bp.Instant;
+import org.threeten.bp.LocalDateTime;
+import org.threeten.bp.ZoneId;
+import org.threeten.bp.format.DateTimeFormatter;
+import org.threeten.bp.format.TextStyle;
+
+import java.util.Locale;
+
+
+public class TimeDispose {
+
+    private static final DateTimeFormatter HH_MM = DateTimeFormatter.ofPattern("HH:mm");
+    private static final DateTimeFormatter MMDD = DateTimeFormatter.ofPattern("MM-dd");
+
+    public static final int[][] INTERCALARY = new int[][]{
+            {2023, 2}, {2025, 6}, {2028, 5}, {2031, 3}, {2033, 11}, {2036, 6},
+            {2039, 5}, {2042, 2}, {2044, 7}, {2047, 5}
+    };
+
+    private MutableLiveData<Integer> mTimeQuantumLiveData;
+    private MutableLiveData<SparseArray<String>> mWeekDateLiveData;
+    private MutableLiveData<String> mTimeLiveData;
+    private MutableLiveData<SparseArray<String>> mLunarCalendarLiveData;
+
+    private MutableLiveData<String> mObsTime;
+    private MutableLiveData<String> mObsYear;
+    private MutableLiveData<String> mObsWeek;
+
+    private int mToday = -1;
+    private int mHour=-1;
+
+    public TimeDispose() {
+        mTimeQuantumLiveData = new MutableLiveData<>();
+        mWeekDateLiveData = new MutableLiveData<>();
+        mTimeLiveData = new MutableLiveData<>();
+        mLunarCalendarLiveData = new MutableLiveData<>();
+
+        mObsTime = new MutableLiveData<>();
+        mObsYear = new MutableLiveData<>();
+        mObsWeek = new MutableLiveData<>();
+
+        analysisDataTimeValue(null);
+    }
+
+    public LiveData<Integer> getTimeQuantumLiveData() {
+        return mTimeQuantumLiveData;
+    }
+
+    public LiveData<SparseArray<String>> getWeekDateLiveData() {
+        return mWeekDateLiveData;
+    }
+
+    public LiveData<String> getTimeLiveData() {
+        return mTimeLiveData;
+    }
+
+    public LiveData<SparseArray<String>> getLunarCalendarLiveData() {
+        return mLunarCalendarLiveData;
+    }
+
+    public MutableLiveData<String> getObsTime() {
+        return mObsTime;
+    }
+
+    public MutableLiveData<String> getObsYear() {
+        return mObsYear;
+    }
+
+    public MutableLiveData<String> getObsWeek() {
+        return mObsWeek;
+    }
+
+    public void registerTimeDateReceiver(Context context) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_TIME_TICK);
+        filter.addAction(Intent.ACTION_TIME_CHANGED);
+        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+        context.registerReceiver(mIntentReceiver, filter);
+    }
+
+    public void unRegisterTimeDateReceiver(Context context) {
+        try {
+            context.unregisterReceiver(mIntentReceiver);
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (TextUtils.isEmpty(action)) return;
+
+            if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
+                analysisDataTimeValue(intent.getStringExtra("time-zone"));
+            } else {
+                analysisDataTimeValue(null);
+            }
+        }
+    };
+
+    private void analysisDataTimeValue(String z) {
+
+        LocalDateTime currDateTime;
+
+        if (!TextUtils.isEmpty(z)) {
+            ZoneId zone = ZoneId.of(z).getRules().getOffset(Instant.now());
+            currDateTime = LocalDateTime.now(zone);
+        } else {
+            currDateTime = LocalDateTime.now(ZoneId.systemDefault());
+        }
+
+        int product = BuildConfig.productType;
+
+        if(product == 1001){
+            mTimeLiveData.setValue(currDateTime.format(HH_MM));
+
+            int day = currDateTime.getDayOfMonth();
+            if (day != mToday) {
+                mToday=day;
+                setLunarCalender(currDateTime.getYear(), currDateTime.getMonthValue(), day);
+                setWeekData(currDateTime.getDayOfWeek(), day);
+            }
+            int hour = currDateTime.getHour();
+            if(hour != mHour){
+                setTimeQuantum(currDateTime.getHour());
+                mHour=hour;
+            }
+        }
+
+        if(product == 1002){
+            mObsYear.setValue(currDateTime.format(MMDD));
+            mObsTime.setValue(currDateTime.format(HH_MM));
+            mObsWeek.setValue(currDateTime.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.getDefault()));
+        }
+
+    }
+
+    private void setLunarCalender(int year, int month, int day) {
+        SparseArray<String> lunarArray = new SparseArray<>(3);
+        LunarCalendar lunarCalender = LunarCalendar.obtainCalendar(year, month, day);
+        for (int i = 0; i < INTERCALARY.length; i++) {
+            if (INTERCALARY[i][0] == year && INTERCALARY[i][1] == month) {
+                lunarArray.put(0, "1");
+                break;
+            }
+        }
+        lunarArray.put(0, "");
+        lunarArray.put(1, lunarCalender.getLunarMonth());
+        lunarArray.put(2, lunarCalender.getLunarDay());
+        mLunarCalendarLiveData.setValue(lunarArray);
+    }
+
+    private void setWeekData(DayOfWeek dayOfWeek, int day) {
+        SparseArray<String> dataArray = new SparseArray<>(2);
+        dataArray.put(0, String.valueOf(day));
+        dataArray.put(1, dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.getDefault()));
+        mWeekDateLiveData.setValue(dataArray);
+    }
+
+    private void setTimeQuantum(int hour) {
+        int value =7;
+        if( hour >=3 && hour < 6){
+            value=0;
+        }else if(hour >=6 && hour < 8){
+            value=1;
+        }else if(hour >=8 && hour < 11){
+            value=2;
+        }else if(hour >=11 && hour < 13){
+            value=3;
+        }else if(hour >=13 && hour < 17){
+            value=4;
+        }else if(hour >=17 && hour < 19){
+            value=5;
+        }else if(hour >=19 && hour < 23){
+            value=6;
+        }
+        mTimeQuantumLiveData.setValue(value);
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/DialogActivity.java b/app/src/main/java/com/ic/ak/launcher/ui/DialogActivity.java
new file mode 100644 (file)
index 0000000..494f059
--- /dev/null
@@ -0,0 +1,185 @@
+package com.ic.ak.launcher.ui;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.KeyEvent;
+
+import com.ic.ak.launcher.BuildConfig;
+import com.ic.ak.launcher.R;
+import com.ic.ak.launcher.data.play.SoundPlayUtils;
+import com.ic.ak.launcher.ui.dialog.BatteryLowManage;
+import com.ic.ak.launcher.ui.dialog.DialogDismissEvent;
+import com.ic.ak.launcher.ui.dialog.NotificationDialogManage;
+import com.ic.ak.launcher.ui.dialog.SedentaryDialogManage;
+import com.ic.ak.launcher.ui.dialog.SlipTipsManage;
+import com.ic.ak.launcher.ui.dialog.TextShowDialogManage;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+public class DialogActivity extends AppCompatActivity {
+
+    private NotificationDialogManage notificationManage;
+    private BatteryLowManage dialogLowManage;
+    private SlipTipsManage dialogSlipManage;
+    private SedentaryDialogManage sedentaryManage;
+    private TextShowDialogManage showDialogManage;
+
+    private SoundPlayUtils soundPlayUtils;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_dialog);
+        EventBus.getDefault().register(this);
+        analysisIntent(getIntent());
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        analysisIntent(intent);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        return true;
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        EventBus.getDefault().unregister(this);
+        notificationManage = null;
+        dialogLowManage = null;
+        dialogSlipManage = null;
+        sedentaryManage = null;
+        showDialogManage = null;
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void onMessageEvent(DialogDismissEvent event) {
+        finish();
+        if(soundPlayUtils != null){
+            soundPlayUtils.stopSoundPlay(16);
+        }
+        switch (event.index) {
+            case 1:
+                if (dialogLowManage != null) {
+                    dialogLowManage.setShowLowTipsFalse();
+                }
+                break;
+            case 2:
+                if (dialogSlipManage != null) {
+                    dialogSlipManage.setSlipTipsFalse();
+                }
+                break;
+            case 3:
+                if (notificationManage != null) {
+                    notificationManage.setNotificationFalse();
+                }
+                break;
+            case 4:
+                if (sedentaryManage != null) {
+                    sedentaryManage.setSedentaryFalse();
+                }
+                break;
+            case 5:
+                if (showDialogManage != null) {
+                    showDialogManage.setTextShowFalse();
+                }
+                break;
+        }
+    }
+
+    private void analysisIntent(Intent intent) {
+        int type = 0;
+        String message = "";
+        if (intent != null) {
+            type = intent.getIntExtra("TYPE", 0);
+            message = intent.getStringExtra("MESSAGE");
+        }
+
+        switch (type) {
+            case 1000:
+            case 1001:
+                if (BuildConfig.productType == 1002) {
+                    if (showDialogManage == null) {
+                        showDialogManage = new TextShowDialogManage();
+                    } else {
+                        showDialogManage.dismissTextShowDialog(getSupportFragmentManager());
+                    }
+                    showDialogManage.showTextShowDialog(getSupportFragmentManager(), message);
+                } else if (BuildConfig.productType == 1001) {
+                    if (notificationManage == null) {
+                        notificationManage = new NotificationDialogManage();
+                    } else {
+                        notificationManage.dismissLowTipsDialog(getSupportFragmentManager());
+                    }
+                    notificationManage.showNotificationDialog(getSupportFragmentManager(), type,message);
+                }
+                break;
+            case 1002:
+                if (BuildConfig.productType == 1001) {
+                    if (sedentaryManage != null) {
+                        return;
+                    }
+                    sedentaryManage = new SedentaryDialogManage();
+                    sedentaryManage.showSedentaryDialog(getSupportFragmentManager());
+                }
+                break;
+            case 1003:
+                if (dialogLowManage != null) {
+                    dialogLowManage.dismissLowTipsDialog(getSupportFragmentManager());
+                }
+                break;
+            case 1004:
+                if (dialogLowManage == null) {
+                    dialogLowManage = new BatteryLowManage();
+                } else {
+                    dialogLowManage.dismissLowTipsDialog(getSupportFragmentManager());
+                }
+                dialogLowManage.showLowTipsDialog(getSupportFragmentManager());
+                break;
+            case 1005:
+                if (dialogSlipManage != null) {
+                    dialogSlipManage.dismissSlipTipsDialog(getSupportFragmentManager());
+                }
+                break;
+            case 1006:
+                playKeyboardSound();
+                if (dialogSlipManage == null) {
+                    dialogSlipManage = new SlipTipsManage();
+                } else {
+                    dialogSlipManage.dismissSlipTipsDialog(getSupportFragmentManager());
+                }
+                dialogSlipManage.showSlipTipsDialog(getSupportFragmentManager());
+                break;
+            case 1007:
+                playKeyboardSound();
+                if (BuildConfig.productType == 1002) {
+                    if (showDialogManage == null) {
+                        showDialogManage = new TextShowDialogManage();
+                    } else {
+                        showDialogManage.dismissTextShowDialog(getSupportFragmentManager());
+                    }
+                    showDialogManage.showTextShowDialog(getSupportFragmentManager(), message);
+                }
+                break;
+        }
+    }
+
+    private void playKeyboardSound(){
+        int type = BuildConfig.productType;
+        if(type == 1002){
+            //A9
+            if(soundPlayUtils == null){
+                soundPlayUtils= new SoundPlayUtils();
+                soundPlayUtils.playKeyboardSound(this,16);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/FragmentAdapter.java b/app/src/main/java/com/ic/ak/launcher/ui/FragmentAdapter.java
new file mode 100644 (file)
index 0000000..26d665b
--- /dev/null
@@ -0,0 +1,33 @@
+package com.ic.ak.launcher.ui;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.lifecycle.Lifecycle;
+import androidx.viewpager2.adapter.FragmentStateAdapter;
+
+import com.ic.ak.launcher.data.app.AppDispose;
+
+
+public class FragmentAdapter extends FragmentStateAdapter {
+
+    private AppDispose appDispose;
+
+    public FragmentAdapter(AppDispose appDispose,
+                           @NonNull FragmentManager fragmentManager,
+                           @NonNull Lifecycle lifecycle) {
+        super(fragmentManager, lifecycle);
+        this.appDispose = appDispose;
+    }
+
+    @NonNull
+    @Override
+    public Fragment createFragment(int position) {
+        return appDispose.getViewPageAdapterFragment(position);
+    }
+
+    @Override
+    public int getItemCount() {
+        return appDispose.getViewPageAdapterSize();
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/IndicatorAdapter.java b/app/src/main/java/com/ic/ak/launcher/ui/IndicatorAdapter.java
new file mode 100644 (file)
index 0000000..52201a2
--- /dev/null
@@ -0,0 +1,63 @@
+package com.ic.ak.launcher.ui;
+
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.ic.ak.launcher.databinding.ItemIndicatorLayoutBinding;
+
+
+public class IndicatorAdapter extends RecyclerView.Adapter<IndicatorAdapter.IndicatorHolder> {
+
+    private boolean[] stateList;
+
+    private int oldCheckIndex=0;
+
+    public IndicatorAdapter(boolean[] state){
+        stateList = state;
+    }
+
+    public void updateIndicatorState(int index){
+        if(oldCheckIndex != index){
+            stateList[index] = true;
+            stateList[oldCheckIndex] =false;
+            oldCheckIndex = index;
+
+            notifyDataSetChanged();
+        }
+    }
+
+    @NonNull
+    @Override
+    public IndicatorHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        return new IndicatorHolder(ItemIndicatorLayoutBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull IndicatorHolder holder, int position) {
+        holder.bindItem(stateList[position]);
+    }
+
+    @Override
+    public int getItemCount() {
+        return stateList.length;
+    }
+
+    static class IndicatorHolder extends RecyclerView.ViewHolder {
+        private ItemIndicatorLayoutBinding binding = null;
+
+        public IndicatorHolder(@NonNull ItemIndicatorLayoutBinding itemView) {
+            super(itemView.getRoot());
+            binding = itemView;
+        }
+
+        public void bindItem(boolean state) {
+            if (binding != null) {
+                binding.setIsCheckItem(state);
+                binding.executePendingBindings();
+            }
+        }
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/MainActivity.java b/app/src/main/java/com/ic/ak/launcher/ui/MainActivity.java
new file mode 100644 (file)
index 0000000..102a1f8
--- /dev/null
@@ -0,0 +1,186 @@
+package com.ic.ak.launcher.ui;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.viewpager2.widget.ViewPager2;
+
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.KeyEvent;
+import android.view.View;
+
+import com.ic.ak.launcher.BuildConfig;
+import com.ic.ak.launcher.LauncherApp;
+import com.ic.ak.launcher.R;
+import com.ic.ak.launcher.data.battery.BatteryConnectStateEvent;
+import com.ic.ak.launcher.data.hardware.HardwareDispose;
+import com.ic.ak.launcher.data.play.SoundPlayUtils;
+import com.ic.ak.launcher.util.ServiceUtil;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+import static androidx.viewpager2.widget.ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT;
+import static java.lang.Math.abs;
+
+public class MainActivity extends AppCompatActivity {
+
+    @BindView(R.id.main_vp)
+    ViewPager2 mainVp;
+
+    @BindView(R.id.indicator_rv)
+    RecyclerView indicatorRv;
+
+    private FragmentAdapter ftAdapter;
+    private IndicatorAdapter indicatorAdapter;
+
+    private LauncherApp mApp;
+    private SoundPlayUtils soundPlayUtils;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (BuildConfig.productType == 1002) {
+            setContentView(R.layout.activity_a9_main);
+        } else if (BuildConfig.productType == 1001) {
+            setContentView(R.layout.activity_main);
+        }
+
+        ButterKnife.bind(this);
+        mApp = (LauncherApp) getApplication();
+
+        indicatorRv.setVisibility(View.GONE);
+
+        initViewPage();
+        initIndicator(mApp.getAppDispose().getIndicatorStateArray());
+
+        mApp.getTimeDispose().registerTimeDateReceiver(this);
+        mApp.getBatteryDispose().registerBatteryReceiver(this);
+        mApp.getHardwareDispose().registerHardwareBroadcast(this);
+
+        EventBus.getDefault().register(this);
+
+        soundPlayUtils = new SoundPlayUtils();
+
+        ServiceUtil.startServiceUtil(getApplicationContext(),
+                "com.ic.action.WORK_SERVICE", getPackageName());
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        //HardwareDispose.testBatteryBroadcast(this,"腕带已佩戴");
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        boolean state = ((LauncherApp) getApplication()).getScreenState();
+        if (!state) {
+            mainVp.setCurrentItem(mApp.getAppDispose().getCenterPosition(), false);
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mApp.getTimeDispose().unRegisterTimeDateReceiver(this);
+        mApp.getBatteryDispose().unRegisterBatteryReceiver(this);
+        mApp.getHardwareDispose().unRegisterHardwareReceiver(this);
+        mApp.getPhoneDispose().stopLoopThread();
+        EventBus.getDefault().unregister(this);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            // 禁用 KEYCODE_BACK 退出功能
+            int position = mainVp.getCurrentItem();
+            int index = mApp.getAppDispose().transformPositionIndicatorIndex(position);
+            if (index != -1) {
+                mainVp.setCurrentItem(mApp.getAppDispose().getCenterPosition(), false);
+            }
+        }
+        return false;
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void onMessageEvent(BatteryConnectStateEvent event) {
+        if (event.state) {
+            soundPlayUtils.playKeyboardSound(this, 0);
+        } else {
+            soundPlayUtils.playKeyboardSound(this, 1);
+        }
+    }
+
+    private void initViewPage() {
+        ftAdapter = new FragmentAdapter(mApp.getAppDispose(), getSupportFragmentManager(), getLifecycle());
+        mainVp.setAdapter(ftAdapter);
+        mainVp.setOffscreenPageLimit(OFFSCREEN_PAGE_LIMIT_DEFAULT);
+        mainVp.setPageTransformer(new CustomPageTransformer());
+        mainVp.setCurrentItem(mApp.getAppDispose().getCenterPosition(), false);
+        mainVp.registerOnPageChangeCallback(scrollListener);
+    }
+
+    private void initIndicator(boolean[] state) {
+        indicatorAdapter = new IndicatorAdapter(state);
+        LinearLayoutManager mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
+        indicatorRv.setLayoutManager(mLayoutManager);
+        indicatorRv.addItemDecoration(new SpacesItemDecoration(5));
+        indicatorRv.setAdapter(indicatorAdapter);
+    }
+
+    private ViewPager2.OnPageChangeCallback scrollListener = new ViewPager2.OnPageChangeCallback() {
+        @Override
+        public void onPageSelected(int position) {
+            super.onPageSelected(position);
+            int index = mApp.getAppDispose().transformPositionIndicatorIndex(position);
+            if (index == -1) {
+                indicatorRv.setVisibility(View.GONE);
+            } else {
+                indicatorRv.setVisibility(View.VISIBLE);
+                indicatorAdapter.updateIndicatorState(index);
+            }
+
+            if (BuildConfig.productType == 1001) {
+                int playId = mApp.getAppDispose().getAppItemPlayItem(position);
+                if (playId != -1) {
+                    int value = Settings.System.getInt(getContentResolver(), "ak_app_play_voice", 0);
+                    if (value == 1001) {
+                        soundPlayUtils.playKeyboardSound(getApplicationContext(), playId);
+                    }
+                }
+            }
+        }
+    };
+
+    private static class CustomPageTransformer implements ViewPager2.PageTransformer {
+        @Override
+        public void transformPage(@NonNull View page, float position) {
+            page.setScaleY(1 - (0.25f * abs(position)));
+            page.setScaleX(1 - (0.25f * abs(position)));
+        }
+    }
+
+    public static class SpacesItemDecoration extends RecyclerView.ItemDecoration {
+        private int space;
+
+        public SpacesItemDecoration(int space) {
+            this.space = space;
+        }
+
+        @Override
+        public void getItemOffsets(Rect outRect, @NonNull View view,
+                                   RecyclerView parent, RecyclerView.State state) {
+            outRect.right = space;
+            outRect.left = space;
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/BatteryLowFragment.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/BatteryLowFragment.java
new file mode 100644 (file)
index 0000000..29d6298
--- /dev/null
@@ -0,0 +1,54 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import androidx.fragment.app.DialogFragment;
+
+import com.ic.ak.launcher.R;
+
+import org.greenrobot.eventbus.EventBus;
+
+
+public class BatteryLowFragment extends DialogFragment {
+
+    public static BatteryLowFragment newInstance() {
+        return new BatteryLowFragment();
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(DialogFragment.STYLE_NORMAL, R.style.TipsDialog);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        Dialog dialog = getDialog();
+        if (dialog != null) {
+            DisplayMetrics dm = new DisplayMetrics();
+            getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
+            dialog.getWindow().setLayout((int) (dm.widthPixels*0.85),180);
+            dialog.setCancelable(false);
+        }
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // Inflate the layout for this fragment
+        View view =  inflater.inflate(R.layout.fragment_image_battery_low, container, false);
+        ImageView btClose = view.findViewById(R.id.slip_bt_close);
+        btClose.setOnClickListener(v ->{
+            EventBus.getDefault().post(new DialogDismissEvent(1));
+            dismiss();
+        });
+        return view;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/BatteryLowManage.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/BatteryLowManage.java
new file mode 100644 (file)
index 0000000..98780d4
--- /dev/null
@@ -0,0 +1,50 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
+public class BatteryLowManage {
+
+    private static final String TAG = "LowTips";
+    private boolean isShowLowTips = false;
+
+    public void setShowLowTipsFalse(){
+        isShowLowTips=false;
+    }
+
+    public void showLowTipsDialog(FragmentManager manager) {
+        if (isShowLowTips || manager == null) {
+            return;
+        }
+        FragmentTransaction ft = manager.beginTransaction();
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            ft.remove(prev);
+        }
+        ft.addToBackStack(null);
+
+        try {
+            // Create and show the dialog.
+            DialogFragment newFragment = BatteryLowFragment.newInstance();
+            newFragment.show(ft, TAG);
+        } catch (IllegalStateException e) {
+        } finally {
+            isShowLowTips = true;
+        }
+    }
+
+    public void dismissLowTipsDialog(FragmentManager manager) {
+        if (!isShowLowTips || manager == null) {
+            return;
+        }
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            DialogFragment df = (DialogFragment) prev;
+            df.dismiss();
+        }
+
+        isShowLowTips = false;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/DialogDismissEvent.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/DialogDismissEvent.java
new file mode 100644 (file)
index 0000000..b2c6d20
--- /dev/null
@@ -0,0 +1,9 @@
+package com.ic.ak.launcher.ui.dialog;
+
+public class DialogDismissEvent {
+    public int index;
+
+    public DialogDismissEvent(int index) {
+        this.index = index;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/NotificationDialogFragment.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/NotificationDialogFragment.java
new file mode 100644 (file)
index 0000000..8a6bb91
--- /dev/null
@@ -0,0 +1,117 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import android.app.Dialog;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+
+import com.ic.ak.launcher.R;
+import com.ic.ak.launcher.util.IcLog;
+import com.ic.ak.launcher.widget.MultiRowTextView;
+
+import org.greenrobot.eventbus.EventBus;
+
+public class NotificationDialogFragment extends DialogFragment {
+
+    private static final String TYPE_PARAM = "TYPE_PARAM";
+    private static final String MESSAGE_PARAM = "MESSAGE_PARAM";
+    private String message;
+    private int type;
+
+    public static NotificationDialogFragment newInstance(int type,String message) {
+        NotificationDialogFragment fragment = new NotificationDialogFragment();
+        Bundle args = new Bundle();
+        args.putString(MESSAGE_PARAM, message);
+        args.putInt(TYPE_PARAM,type);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(DialogFragment.STYLE_NORMAL, R.style.NotificationDialog);
+        if (getArguments() != null) {
+            type = getArguments().getInt(TYPE_PARAM);
+            message = getArguments().getString(MESSAGE_PARAM);
+        }
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        Dialog dialog = getDialog();
+        if (dialog != null) {
+            DisplayMetrics dm = new DisplayMetrics();
+            getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
+            dialog.getWindow().setLayout((int) (dm.widthPixels * 0.95), 180);
+            dialog.setCancelable(false);
+        }
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // Inflate the layout for this fragment
+        View view = inflater.inflate(R.layout.dialog_notification, container, false);
+        MultiRowTextView msgText = view.findViewById(R.id.dialog_message);
+        TextView textView = view.findViewById(R.id.dialog_title);
+        if(type == 1000){
+            textView.setText("短信消息");
+        }
+        Button btClose = view.findViewById(R.id.dialog_bt_close);
+        Button btOpen = view.findViewById(R.id.dialog_bt_open);
+        msgText.setText(message);
+        btClose.setOnClickListener(v -> {
+            EventBus.getDefault().post(new DialogDismissEvent(3));
+            dismiss();
+        });
+
+        btOpen.setOnClickListener(v -> {
+            EventBus.getDefault().post(new DialogDismissEvent(3));
+            if(type == 1000){
+                startMessageActivity();
+            }else if(type == 1001){
+                startNotificationActivity(message);
+            }
+            dismiss();
+        });
+        return view;
+    }
+
+    private void startNotificationActivity(String message) {
+        try {
+            Intent intent = new Intent();
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.putExtra("N_MESSAGE", message);
+            intent.setComponent(new ComponentName(
+                    "com.ic.ak.launcher",
+                    "com.ic.ak.launcher.ui.notification.NotificationActivity"));
+            getActivity().startActivity(intent);
+        } catch (Exception e) {
+        }
+    }
+
+    private void startMessageActivity() {
+        try {
+            Intent intent = new Intent(Intent.ACTION_MAIN);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setComponent(new ComponentName(
+                    "com.ic.message", "com.ic.message.MainActivity"));
+            getActivity().startActivity(intent);
+        } catch (Exception e) {
+            IcLog.e("HardwareDispose","",e);
+        }
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/NotificationDialogManage.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/NotificationDialogManage.java
new file mode 100644 (file)
index 0000000..5c21f72
--- /dev/null
@@ -0,0 +1,59 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
+import com.ic.ak.launcher.R;
+
+public class NotificationDialogManage {
+
+    private static final String TAG = "IcNotification";
+    private boolean isNotificationDialog = false;
+
+    public void setNotificationFalse(){
+        isNotificationDialog=false;
+    }
+
+    public void showNotificationDialog(FragmentManager manager, int type,String message) {
+        if (isNotificationDialog || manager == null) {
+            return;
+        }
+        FragmentTransaction ft = manager.beginTransaction();
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            ft.remove(prev);
+        }
+        ft.addToBackStack(null);
+
+        try {
+            // Create and show the dialog.
+            DialogFragment newFragment = NotificationDialogFragment.newInstance(type,message);
+            newFragment.show(ft, TAG);
+        } catch (IllegalStateException e) {
+        } finally {
+            isNotificationDialog = true;
+        }
+    }
+
+    public void dismissLowTipsDialog(FragmentManager manager) {
+        if (!isNotificationDialog || manager == null) {
+            return;
+        }
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            DialogFragment df = (DialogFragment) prev;
+            df.dismiss();
+        }
+
+        isNotificationDialog = false;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/SedentaryAlarmDialogFragment.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/SedentaryAlarmDialogFragment.java
new file mode 100644 (file)
index 0000000..0324aa8
--- /dev/null
@@ -0,0 +1,54 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+
+import androidx.fragment.app.DialogFragment;
+
+import com.ic.ak.launcher.R;
+
+import org.greenrobot.eventbus.EventBus;
+
+public class SedentaryAlarmDialogFragment extends DialogFragment {
+
+    public static SedentaryAlarmDialogFragment newInstance() {
+        return new SedentaryAlarmDialogFragment();
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(DialogFragment.STYLE_NORMAL, R.style.TipsDialog);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        Dialog dialog = getDialog();
+        if (dialog != null) {
+            DisplayMetrics dm = new DisplayMetrics();
+            getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
+            dialog.getWindow().setLayout(dm.widthPixels, dm.heightPixels);
+            dialog.setCancelable(false);
+        }
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // Inflate the layout for this fragment
+        View view = inflater.inflate(R.layout.dialog_sedentary_alarm, container, false);
+        ImageView btClose = view.findViewById(R.id.sedentary_close);
+        btClose.setOnClickListener(v -> {
+            EventBus.getDefault().post(new DialogDismissEvent(4));
+            dismiss();
+        });
+        return view;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/SedentaryDialogManage.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/SedentaryDialogManage.java
new file mode 100644 (file)
index 0000000..1d9ddfb
--- /dev/null
@@ -0,0 +1,50 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
+public class SedentaryDialogManage {
+
+    private static final String TAG = "IcSedentary";
+    private boolean isNotificationDialog = false;
+
+    public void setSedentaryFalse(){
+        isNotificationDialog=false;
+    }
+
+    public void showSedentaryDialog(FragmentManager manager) {
+        if (isNotificationDialog || manager == null) {
+            return;
+        }
+        FragmentTransaction ft = manager.beginTransaction();
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            ft.remove(prev);
+        }
+        ft.addToBackStack(null);
+
+        try {
+            // Create and show the dialog.
+            DialogFragment newFragment = SedentaryAlarmDialogFragment.newInstance();
+            newFragment.show(ft, TAG);
+        } catch (IllegalStateException e) {
+        } finally {
+            isNotificationDialog = true;
+        }
+    }
+
+    public void dismissSedentaryDialog(FragmentManager manager) {
+        if (!isNotificationDialog || manager == null) {
+            return;
+        }
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            DialogFragment df = (DialogFragment) prev;
+            df.dismiss();
+        }
+
+        isNotificationDialog = false;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/SlipTipsFragment.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/SlipTipsFragment.java
new file mode 100644 (file)
index 0000000..52000a0
--- /dev/null
@@ -0,0 +1,55 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import androidx.fragment.app.DialogFragment;
+
+import com.ic.ak.launcher.R;
+
+import org.greenrobot.eventbus.EventBus;
+
+
+public class SlipTipsFragment extends DialogFragment {
+
+
+    public static SlipTipsFragment newInstance() {
+        return new SlipTipsFragment();
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(DialogFragment.STYLE_NORMAL, R.style.TipsDialog);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        Dialog dialog = getDialog();
+        if (dialog != null) {
+            DisplayMetrics dm = new DisplayMetrics();
+            getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
+            dialog.getWindow().setLayout((int) (dm.widthPixels*0.85),180);
+            dialog.setCancelable(false);
+        }
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // Inflate the layout for this fragment
+        View view =  inflater.inflate(R.layout.fragment_image_slip, container, false);
+        ImageView btClose = view.findViewById(R.id.slip_bt_close);
+        btClose.setOnClickListener(v ->{
+            EventBus.getDefault().post(new DialogDismissEvent(2));
+            dismiss();
+        });
+        return view;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/SlipTipsManage.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/SlipTipsManage.java
new file mode 100644 (file)
index 0000000..0c80bc6
--- /dev/null
@@ -0,0 +1,50 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
+public class SlipTipsManage {
+
+    private static final String TAG = "SlipTips";
+    private boolean isShowSlipTips = false;
+
+    public void setSlipTipsFalse(){
+        isShowSlipTips=false;
+    }
+
+    public void showSlipTipsDialog(FragmentManager manager) {
+        if (isShowSlipTips || manager == null) {
+            return;
+        }
+        FragmentTransaction ft = manager.beginTransaction();
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            ft.remove(prev);
+        }
+        ft.addToBackStack(null);
+
+        try {
+            // Create and show the dialog.
+            DialogFragment newFragment = SlipTipsFragment.newInstance();
+            newFragment.show(ft, TAG);
+        } catch (IllegalStateException e) {
+        } finally {
+            isShowSlipTips = true;
+        }
+    }
+
+    public void dismissSlipTipsDialog(FragmentManager manager) {
+        if (!isShowSlipTips || manager == null) {
+            return;
+        }
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            DialogFragment df = (DialogFragment) prev;
+            df.dismiss();
+        }
+
+        isShowSlipTips = false;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/TextShowDialogFragment.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/TextShowDialogFragment.java
new file mode 100644 (file)
index 0000000..289e447
--- /dev/null
@@ -0,0 +1,67 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.fragment.app.DialogFragment;
+
+import com.ic.ak.launcher.R;
+
+import org.greenrobot.eventbus.EventBus;
+
+
+public class TextShowDialogFragment extends DialogFragment {
+
+    private static final String MESSAGE_PARAM = "MESSAGE_PARAM";
+    private String message;
+
+    public static TextShowDialogFragment newInstance(String message) {
+        TextShowDialogFragment fragment = new TextShowDialogFragment();
+        Bundle args = new Bundle();
+        args.putString(MESSAGE_PARAM, message);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(DialogFragment.STYLE_NORMAL, R.style.TipsDialog);
+        if (getArguments() != null) {
+            message = getArguments().getString(MESSAGE_PARAM);
+        }
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        Dialog dialog = getDialog();
+        if (dialog != null) {
+            DisplayMetrics dm = new DisplayMetrics();
+            getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
+            dialog.getWindow().setLayout((int) (dm.widthPixels*0.85),180);
+            dialog.setCancelable(false);
+        }
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // Inflate the layout for this fragment
+        View view =  inflater.inflate(R.layout.dialog_text_show_a9, container, false);
+        TextView textMessage = view.findViewById(R.id.message_tips_id);
+        ImageView btClose = view.findViewById(R.id.slip_bt_close);
+        textMessage.setText(message);
+        btClose.setOnClickListener(v ->{
+            EventBus.getDefault().post(new DialogDismissEvent(5));
+            dismiss();
+        });
+        return view;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/dialog/TextShowDialogManage.java b/app/src/main/java/com/ic/ak/launcher/ui/dialog/TextShowDialogManage.java
new file mode 100644 (file)
index 0000000..19013d9
--- /dev/null
@@ -0,0 +1,50 @@
+package com.ic.ak.launcher.ui.dialog;
+
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
+public class TextShowDialogManage {
+
+    private static final String TAG = "IcA9TextShow";
+    private boolean isShowDialog = false;
+
+    public void setTextShowFalse(){
+        isShowDialog=false;
+    }
+
+    public void showTextShowDialog(FragmentManager manager,String message) {
+        if (isShowDialog || manager == null) {
+            return;
+        }
+        FragmentTransaction ft = manager.beginTransaction();
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            ft.remove(prev);
+        }
+        ft.addToBackStack(null);
+
+        try {
+            // Create and show the dialog.
+            DialogFragment newFragment = TextShowDialogFragment.newInstance(message);
+            newFragment.show(ft, TAG);
+        } catch (IllegalStateException e) {
+        } finally {
+            isShowDialog = true;
+        }
+    }
+
+    public void dismissTextShowDialog(FragmentManager manager) {
+        if (!isShowDialog || manager == null) {
+            return;
+        }
+        Fragment prev = manager.findFragmentByTag(TAG);
+        if (prev != null) {
+            DialogFragment df = (DialogFragment) prev;
+            df.dismiss();
+        }
+
+        isShowDialog = false;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/fragment/AppFragment.java b/app/src/main/java/com/ic/ak/launcher/ui/fragment/AppFragment.java
new file mode 100644 (file)
index 0000000..7909e11
--- /dev/null
@@ -0,0 +1,128 @@
+package com.ic.ak.launcher.ui.fragment;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.fragment.app.Fragment;
+
+
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.ic.ak.launcher.BuildConfig;
+import com.ic.ak.launcher.LauncherApp;
+import com.ic.ak.launcher.R;
+import com.ic.ak.launcher.data.app.AppItem;
+import com.ic.ak.launcher.data.phone.CallPhone;
+
+import org.greenrobot.eventbus.EventBus;
+
+import butterknife.BindString;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+
+public class AppFragment extends Fragment {
+
+    @BindView(R.id.app_icon)
+    ImageView appIcon;
+
+    @BindView(R.id.app_title)
+    TextView appTitle;
+
+    @BindString(R.string.tips_start_activity)
+    String tipsStartActivity;
+
+    private Context context;
+    private AppItem mAppItem;
+
+    public static AppFragment newInstance(AppItem appItem) {
+        AppFragment fragment = new AppFragment();
+        Bundle args = new Bundle();
+        args.putParcelable("ITEM_PARAM", appItem);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @Override
+    public void onAttach(@NonNull Context context) {
+        super.onAttach(context);
+        this.context=context;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (getArguments() != null) {
+            mAppItem = getArguments().getParcelable("ITEM_PARAM");
+        }
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        View view=null;
+        if(BuildConfig.productType == 1002){
+            view = inflater.inflate(R.layout.fragment_a9_app, container, false);
+        } else if(BuildConfig.productType == 1001){
+            view = inflater.inflate(R.layout.fragment_app, container, false);
+        }
+        ButterKnife.bind(this,view);
+        appTitle.setText(getResources().getString(mAppItem.getTitleResId()));
+        appIcon.setImageResource(mAppItem.getIconResId());
+
+        return view;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        /**int index = mAppItem.getPlayVoiceIndex();
+        if(index != -1){
+            int value =  Settings.System.getInt(context.getContentResolver(), "ak_app_play_voice", 0);
+            if(value == 1001){
+                EventBus.getDefault().post(new AppVoicePlayEvent(index));
+            }
+        }**/
+    }
+
+    @OnClick(R.id.app_item)
+    void onClickAppItem(View view){
+        String pack = mAppItem.getAppPackage();
+        String main = mAppItem.getAppMainClass();
+
+        if(mAppItem.getTitleResId() == R.string.app_title_living_home){
+            new CallPhone().callPhone((LauncherApp) getContext().getApplicationContext(),"07522212349");
+            return;
+        }
+
+        if(TextUtils.isEmpty(pack) || TextUtils.isEmpty(main)){
+            showToast(getContext(),tipsStartActivity);
+            return;
+        }
+
+        try {
+            Intent intent = new Intent(Intent.ACTION_MAIN);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setComponent(new ComponentName(pack, main));
+            getContext().startActivity(intent);
+        }catch (Exception e){
+            showToast(getContext(),tipsStartActivity);
+        }
+    }
+
+    private void showToast(Context context,String message){
+        Toast.makeText(context,message,Toast.LENGTH_LONG).show();
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/fragment/AppVoicePlayEvent.java b/app/src/main/java/com/ic/ak/launcher/ui/fragment/AppVoicePlayEvent.java
new file mode 100644 (file)
index 0000000..79cc597
--- /dev/null
@@ -0,0 +1,9 @@
+package com.ic.ak.launcher.ui.fragment;
+
+public class AppVoicePlayEvent {
+    public int index;
+
+    public AppVoicePlayEvent(int index) {
+        this.index = index;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainA9Fragment.java b/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainA9Fragment.java
new file mode 100644 (file)
index 0000000..83ff99e
--- /dev/null
@@ -0,0 +1,161 @@
+package com.ic.ak.launcher.ui.fragment;
+
+import android.content.Context;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.ic.ak.launcher.LauncherApp;
+import com.ic.ak.launcher.R;
+import com.ic.ak.launcher.databinding.FragmentA9MainBinding;
+import com.ic.ak.launcher.util.SPUtils;
+
+import butterknife.BindDrawable;
+import butterknife.ButterKnife;
+
+
+public class MainA9Fragment extends Fragment {
+
+    @BindDrawable(R.mipmap.a9_battery_5)
+    Drawable akBattery;
+
+    @BindDrawable(R.drawable.battery_charging_anim_a9)
+    Drawable batteryCharge;
+
+
+    private FragmentA9MainBinding mainBinding;
+
+    private MainA9ViewModel mainViewModel;
+    private boolean chargingState;
+    private AnimationDrawable animationDrawable;
+
+
+    public static MainA9Fragment newInstance() {
+        return new MainA9Fragment();
+    }
+
+    @Override
+    public void onAttach(@NonNull Context context) {
+        super.onAttach(context);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        MainA9ViewModel.Factory factory = new MainA9ViewModel.Factory((LauncherApp) getContext().getApplicationContext());
+        mainViewModel = new ViewModelProvider(this, factory).get(MainA9ViewModel.class);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // Inflate the layout for this fragment
+        mainBinding = FragmentA9MainBinding.inflate(inflater, container, false);
+        ButterKnife.bind(this, mainBinding.getRoot());
+        mainBinding.setBatteryIcon(akBattery);
+        mainBinding.setPed("0");
+        mainBinding.setHeart(SPUtils.getBloodHeartSP(getContext()));
+        observePhoneViewModel();
+        observeTimeViewModel();
+        observeBatteryViewModel();
+        observeHardwareValue();
+        return mainBinding.getRoot();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mainViewModel.resumeQueryThread();
+        mainViewModel.sendGetPedBroadcast(getContext());
+        if (chargingState) {
+            updateBatteryChargeState(true);
+        }
+        //mainViewModel.testBatteryBroadcast(getContext(), 1);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mainViewModel.pauseQueryThread();
+        if (chargingState) {
+            updateBatteryChargeState(false);
+        }
+    }
+
+    private void observePhoneViewModel() {
+        mainViewModel.getTypeID().observe(getViewLifecycleOwner(), type -> {
+            mainBinding.setPhoneTypeIcon(getResources().getDrawable(type));
+        });
+
+        mainViewModel.getSignalID().observe(getViewLifecycleOwner(), signal -> {
+            mainBinding.setSignalIcon(getResources().getDrawable(signal));
+        });
+
+        mainViewModel.getSimCardState().observe(getViewLifecycleOwner(), state -> mainBinding.setIsNotSim(!state));
+    }
+
+    private void observeTimeViewModel() {
+        mainViewModel.getObservableTime().observe(getViewLifecycleOwner(), time -> mainBinding.setTimeNumber(time));
+        mainViewModel.getObservableWeek().observe(getViewLifecycleOwner(), week -> mainBinding.setWeek(week));
+        mainViewModel.getObservableYear().observe(getViewLifecycleOwner(), year -> mainBinding.setDate(year));
+    }
+
+    private void observeBatteryViewModel() {
+        mainViewModel.getBatteryChargingLiveData().observe(getViewLifecycleOwner(), charging -> {
+            if (chargingState != charging) {
+                chargingState = charging;
+                updateBatteryChargeState(chargingState);
+            }
+        });
+
+        mainViewModel.getBatteryResIDLiveData().observe(getViewLifecycleOwner(), resID -> {
+            mainBinding.setBatteryIcon(getResources().getDrawable(resID));
+        });
+
+        mainViewModel.getBatteryValueLiveData().observe(getViewLifecycleOwner(), value -> {
+            mainBinding.setBatteryValue(value + "%");
+        });
+    }
+
+    private void observeHardwareValue() {
+        mainViewModel.getObservableHardwareHeart().observe(this, heart -> {
+            if (mainBinding != null) {
+                mainBinding.setHeart(heart);
+                SPUtils.setBloodHeartSP(getContext(), heart);
+            }
+        });
+
+        mainViewModel.getObservableHardwarePed().observe(this, ped -> {
+            if (mainBinding != null) {
+                mainBinding.setPed(ped);
+            }
+        });
+    }
+
+    private void updateBatteryChargeState(boolean charging) {
+        if (charging) {
+            if (animationDrawable != null) {
+                mainBinding.setBatteryIcon(batteryCharge);
+                animationDrawable = (AnimationDrawable) mainBinding.getBatteryIcon();
+                mainBinding.batteryIv.getViewTreeObserver().addOnDrawListener(() -> {
+                            if (animationDrawable != null) {
+                                animationDrawable.start();
+                            }
+                        }
+                );
+            }
+        } else {
+            if (animationDrawable != null) {
+                animationDrawable.stop();
+                animationDrawable = null;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainA9ViewModel.java b/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainA9ViewModel.java
new file mode 100644 (file)
index 0000000..44af851
--- /dev/null
@@ -0,0 +1,104 @@
+package com.ic.ak.launcher.ui.fragment;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.ic.ak.launcher.LauncherApp;
+import com.ic.ak.launcher.data.battery.BatteryDispose;
+import com.ic.ak.launcher.data.hardware.HardwareDispose;
+import com.ic.ak.launcher.data.phone.PhoneDispose;
+import com.ic.ak.launcher.data.time.TimeDispose;
+
+public class MainA9ViewModel extends ViewModel {
+
+    private TimeDispose timeDispose;
+    private BatteryDispose batteryDispose;
+    private PhoneDispose phoneDispose;
+    private HardwareDispose hardwareDispose;
+
+    public MainA9ViewModel(TimeDispose timeDispose, BatteryDispose batteryDispose, PhoneDispose phoneDispose, HardwareDispose hardwareDispose) {
+        this.timeDispose = timeDispose;
+        this.batteryDispose=batteryDispose;
+        this.phoneDispose=phoneDispose;
+        this.hardwareDispose=hardwareDispose;
+    }
+
+    public static class Factory extends ViewModelProvider.NewInstanceFactory {
+
+        @NonNull
+        private final LauncherApp app;
+
+
+        public Factory(@NonNull LauncherApp application) {
+            app = application;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        @NonNull
+        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
+            return (T) new MainA9ViewModel(app.getTimeDispose(),app.getBatteryDispose(),app.getPhoneDispose(),app.getHardwareDispose());
+        }
+    }
+
+    public LiveData<String> getObservableTime() {
+        return timeDispose.getObsTime();
+    }
+
+    public LiveData<String> getObservableWeek() {
+        return timeDispose.getObsWeek();
+    }
+
+    public LiveData<String> getObservableYear() {
+        return timeDispose.getObsYear();
+    }
+
+    public LiveData<Integer> getTypeID() {
+        return phoneDispose.getTypeID();
+    }
+
+    public LiveData<Integer> getSignalID() {
+        return phoneDispose.getSignalID();
+    }
+
+    public LiveData<Boolean> getSimCardState() {
+        return phoneDispose.getSimCardState();
+    }
+
+    public void resumeQueryThread() {
+        phoneDispose.resumeQueryThread();
+    }
+
+    public void pauseQueryThread() {
+        phoneDispose.pauseQueryThread();
+    }
+
+    public LiveData<Boolean> getBatteryChargingLiveData() {
+        return batteryDispose.getBatteryChargingLiveData();
+    }
+
+    public LiveData<Integer> getBatteryResIDLiveData() {
+        return batteryDispose.getBatteryResIDLiveData();
+    }
+
+    public MutableLiveData<String> getBatteryValueLiveData() {
+        return batteryDispose.getBatteryValueLiveData();
+    }
+
+    public LiveData<String> getObservableHardwareHeart() {
+        return hardwareDispose.getObsHardwareHeart();
+    }
+
+    public LiveData<String> getObservableHardwarePed() {
+        return hardwareDispose.getObsHardwarePed();
+    }
+
+    public void sendGetPedBroadcast(Context context) {
+        hardwareDispose.sendGetPedBroadcast(context);
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainFragment.java b/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainFragment.java
new file mode 100644 (file)
index 0000000..082dbd1
--- /dev/null
@@ -0,0 +1,225 @@
+package com.ic.ak.launcher.ui.fragment;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProvider;
+
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.ic.ak.launcher.LauncherApp;
+import com.ic.ak.launcher.R;
+import com.ic.ak.launcher.data.battery.BatteryDispose;
+import com.ic.ak.launcher.databinding.FragmentMainBinding;
+import com.ic.ak.launcher.util.IcLog;
+
+import java.lang.ref.WeakReference;
+
+import butterknife.BindDrawable;
+import butterknife.BindString;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+
+public class MainFragment extends Fragment {
+    @BindString(R.string.time_wee_hours)
+    String timeWeeHours;
+    @BindString(R.string.time_morning)
+    String timeMorning;
+    @BindString(R.string.time_am)
+    String timeAm;
+    @BindString(R.string.time_noon)
+    String timeNoon;
+    @BindString(R.string.time_pm)
+    String timePm;
+    @BindString(R.string.time_at_dusk)
+    String timeAtDusk;
+    @BindString(R.string.time_evening)
+    String timeEvening;
+    @BindString(R.string.time_night)
+    String timeNight;
+
+    @BindDrawable(R.mipmap.ak_battery_5)
+    Drawable akBattery;
+
+    @BindString(R.string.lunar_show_str)
+    String lunarStr;
+
+    @BindString(R.string.lunar_intercalary)
+    String lunarIntercalary;
+
+    @BindString(R.string.time_date_week_str)
+    String timeDateWeek;
+
+    @BindDrawable(R.drawable.battery_charging_anim_ak)
+    Drawable batteryCharge;
+
+    private FragmentMainBinding mainBinding;
+
+    private MainViewModel mainViewModel;
+
+    private String[] mQuantumStr;
+    private boolean chargingState;
+
+    private AnimationHandler animationHandler;
+    private int mIndex=0;
+
+    public static MainFragment newInstance() {
+        return new MainFragment();
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        MainViewModel.Factory factory = new MainViewModel.Factory((LauncherApp) getContext().getApplicationContext());
+        mainViewModel = new ViewModelProvider(this,factory).get(MainViewModel.class);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // Inflate the layout for this fragment
+        mainBinding = FragmentMainBinding.inflate(inflater, container, false);
+        ButterKnife.bind(this, mainBinding.getRoot());
+        mQuantumStr = new String[]{timeWeeHours, timeMorning, timeAm, timeNoon, timePm, timeAtDusk, timeEvening, timeNight};
+        mainBinding.setBatteryIcon(akBattery);
+        animationHandler = new AnimationHandler(this);
+        observePhoneViewModel();
+        observeTimeViewModel();
+        observeBatteryViewModel();
+
+        return mainBinding.getRoot();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mainViewModel.resumeQueryThread();
+        if (chargingState) {
+            updateBatteryChargeState(true);
+        }
+
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mainViewModel.pauseQueryThread();
+        if (chargingState) {
+            updateBatteryChargeState(false);
+        }
+    }
+
+    @OnClick(R.id.bt_family_contacts)
+    void startFamilyContacts(View view){
+        try {
+            Intent intent = new Intent();
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.putExtra("C_TYPE",0);
+            intent.setComponent(new ComponentName("com.ic.ak.hardware", "com.ic.ak.hardware.ui.FamilyContactsActivity"));
+            getContext().startActivity(intent);
+        }catch (Exception e){
+        }
+    }
+
+    private void observePhoneViewModel() {
+        mainViewModel.getTypeID().observe(getViewLifecycleOwner(), type -> {
+            mainBinding.setPhoneTypeIcon(getResources().getDrawable(type));
+        });
+
+        mainViewModel.getSignalID().observe(getViewLifecycleOwner(), signal -> {
+            mainBinding.setSignalIcon(getResources().getDrawable(signal));
+        });
+
+        mainViewModel.getTransportID().observe(getViewLifecycleOwner(), transport -> {
+            mainBinding.setTransportIcon(getResources().getDrawable(transport));
+        });
+
+        mainViewModel.getSimCardState().observe(getViewLifecycleOwner(), state -> mainBinding.setIsNotSim(!state));
+    }
+
+    private void observeTimeViewModel() {
+        mainViewModel.getLunarCalendarLiveData().observe(getViewLifecycleOwner(), lunar -> {
+            if (TextUtils.isEmpty(lunar.get(0))) {
+                mainBinding.setTimeLunar(String.format(lunarStr, "", lunar.get(1), lunar.get(2)));
+            } else {
+                mainBinding.setTimeLunar(String.format(lunarStr, lunarIntercalary, lunar.get(1), lunar.get(2)));
+            }
+        });
+
+        mainViewModel.getTimeLiveData().observe(getViewLifecycleOwner(), time -> mainBinding.setTimeNumber(time));
+
+        mainViewModel.getWeekDateLiveData().observe(getViewLifecycleOwner(), week -> mainBinding.setWeekDate(String.format(timeDateWeek, week.get(0), week.get(1))));
+
+        mainViewModel.getTimeQuantumLiveData().observe(getViewLifecycleOwner(), quantum -> mainBinding.setTimeQuantum(mQuantumStr[quantum]));
+    }
+
+    private void observeBatteryViewModel() {
+        mainViewModel.getBatteryChargingLiveData().observe(getViewLifecycleOwner(), charging -> {
+            if (chargingState != charging) {
+                chargingState = charging;
+                updateBatteryChargeState(chargingState);
+            }
+        });
+
+        mainViewModel.getBatteryResIDLiveData().observe(getViewLifecycleOwner(), resID -> {
+            mainBinding.setBatteryIcon(getResources().getDrawable(resID));
+        });
+
+        mainViewModel.getBatteryValueLiveData().observe(getViewLifecycleOwner(), value -> {
+            mainBinding.setBatteryValue(value + "%");
+        });
+    }
+
+    private void updateBatteryChargeState(boolean charging) {
+        if(charging){
+            animationHandler.sendEmptyMessage(1);
+        }else{
+            animationHandler.removeMessages(1);
+            mIndex=0;
+        }
+    }
+
+    private void startBatteryChargeAnimation(){
+        int[] batteryResId  = BatteryDispose.getCurrentProductBatteryResId();
+        if(mIndex >= batteryResId.length){
+            mIndex=0;
+        }
+        mainBinding.setBatteryIcon(getResources().getDrawable(batteryResId[mIndex]));
+        mIndex++;
+        animationHandler.sendEmptyMessageDelayed(1,1000);
+    }
+
+    private static class AnimationHandler extends Handler {
+
+        private WeakReference<MainFragment> weakReference;
+
+        public AnimationHandler(MainFragment view) {
+            this.weakReference = new WeakReference<>(view);
+        }
+
+        @Override
+        public void dispatchMessage(@NonNull Message msg) {
+            super.dispatchMessage(msg);
+            switch (msg.what){
+                case 1:
+                    MainFragment fragment = weakReference.get();
+                    if(fragment != null && fragment.isAdded()){
+                        fragment.startBatteryChargeAnimation();
+                    }
+                    break;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainViewModel.java b/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainViewModel.java
new file mode 100644 (file)
index 0000000..3562671
--- /dev/null
@@ -0,0 +1,99 @@
+package com.ic.ak.launcher.ui.fragment;
+
+import android.app.Application;
+import android.util.SparseArray;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.ic.ak.launcher.LauncherApp;
+import com.ic.ak.launcher.data.battery.BatteryDispose;
+import com.ic.ak.launcher.data.phone.PhoneDispose;
+import com.ic.ak.launcher.data.time.TimeDispose;
+
+public class MainViewModel extends ViewModel {
+
+    private TimeDispose timeDispose;
+    private BatteryDispose batteryDispose;
+    private PhoneDispose phoneDispose;
+
+    public MainViewModel(TimeDispose timeDispose, BatteryDispose batteryDispose, PhoneDispose phoneDispose) {
+        this.timeDispose = timeDispose;
+        this.batteryDispose=batteryDispose;
+        this.phoneDispose=phoneDispose;
+    }
+
+    public static class Factory extends ViewModelProvider.NewInstanceFactory {
+
+        @NonNull
+        private final LauncherApp app;
+
+
+        public Factory(@NonNull LauncherApp application) {
+            app = application;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        @NonNull
+        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
+            return (T) new MainViewModel(app.getTimeDispose(),app.getBatteryDispose(),app.getPhoneDispose());
+        }
+    }
+
+    public LiveData<Integer> getTimeQuantumLiveData() {
+        return timeDispose.getTimeQuantumLiveData();
+    }
+
+    public LiveData<SparseArray<String>> getWeekDateLiveData() {
+        return timeDispose.getWeekDateLiveData();
+    }
+
+    public LiveData<String> getTimeLiveData() {
+        return timeDispose.getTimeLiveData();
+    }
+
+    public LiveData<SparseArray<String>> getLunarCalendarLiveData() {
+        return timeDispose.getLunarCalendarLiveData();
+    }
+
+    public LiveData<Boolean> getBatteryChargingLiveData() {
+        return batteryDispose.getBatteryChargingLiveData();
+    }
+
+    public LiveData<Integer> getBatteryResIDLiveData() {
+        return batteryDispose.getBatteryResIDLiveData();
+    }
+
+    public MutableLiveData<String> getBatteryValueLiveData() {
+        return batteryDispose.getBatteryValueLiveData();
+    }
+
+
+    public LiveData<Integer> getTypeID() {
+        return phoneDispose.getTypeID();
+    }
+
+    public LiveData<Integer> getSignalID() {
+        return phoneDispose.getSignalID();
+    }
+
+    public LiveData<Integer> getTransportID() {
+        return phoneDispose.getTransportID();
+    }
+
+    public LiveData<Boolean> getSimCardState() {
+        return phoneDispose.getSimCardState();
+    }
+
+    public void resumeQueryThread() {
+        phoneDispose.resumeQueryThread();
+    }
+
+    public void pauseQueryThread() {
+        phoneDispose.pauseQueryThread();
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/ui/notification/NotificationActivity.java b/app/src/main/java/com/ic/ak/launcher/ui/notification/NotificationActivity.java
new file mode 100644 (file)
index 0000000..f8a5786
--- /dev/null
@@ -0,0 +1,49 @@
+package com.ic.ak.launcher.ui.notification;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.TextView;
+
+import com.ic.ak.launcher.R;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+public class NotificationActivity extends AppCompatActivity {
+
+    @BindView(R.id.notification_message)
+    TextView msgTextView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_notification);
+        ButterKnife.bind(this);
+
+        Intent intent = getIntent();
+        String message = null;
+        if(intent != null){
+            message = intent.getStringExtra("N_MESSAGE");
+        }
+        msgTextView.setText(message);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            // 禁用 KEYCODE_BACK 退出功能
+            finish();
+        }
+        return true;
+    }
+
+    @OnClick(R.id.notification_bt_ok)
+    public void onBtOk(View view){
+        finish();
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ic/ak/launcher/util/CrashHandler.java b/app/src/main/java/com/ic/ak/launcher/util/CrashHandler.java
new file mode 100644 (file)
index 0000000..6d39a71
--- /dev/null
@@ -0,0 +1,213 @@
+package com.ic.ak.launcher.util;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Environment;
+import android.os.Looper;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.ic.ak.launcher.R;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.reflect.Field;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Created by Administrator on 2017/5/18.
+ */
+
+public class CrashHandler implements Thread.UncaughtExceptionHandler {
+    public static final String TAG = CrashHandler.class.getName();
+
+    // 系统默认的UncaughtException处理类
+    private Thread.UncaughtExceptionHandler mDefaultHandler;
+    // CrashHandler实例
+    private static CrashHandler INSTANCE = new CrashHandler();
+    // 程序的Context对象
+    private Context mContext;
+    // 用来存储设备信息和异常信息
+    private Map<String, String> infos = new HashMap<String, String>();
+    // 用于格式化日期,作为日志文件名的一部分
+    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS", Locale.getDefault());
+    private DateFormat dateFormatDate = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
+
+    /**
+     * 保证只有一个CrashHandler实例
+     */
+    private CrashHandler() {
+    }
+
+    /**
+     * 获取CrashHandler实例 ,单例模式
+     */
+    public static CrashHandler getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * 初始化
+     *
+     * @param context
+     */
+    public void init(Context context) {
+        mContext = context;
+        // 获取系统默认的UncaughtException处理器
+        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
+        // 设置该CrashHandler为程序的默认处理器
+        Thread.setDefaultUncaughtExceptionHandler(this);
+    }
+
+    /**
+     * 当UncaughtException发生时会转入该函数来处理
+     */
+    @Override
+    public void uncaughtException(Thread thread, Throwable ex) {
+        if (!handleException(ex) && mDefaultHandler != null) {
+            // 如果用户没有处理则让系统默认的异常处理器来处理
+            mDefaultHandler.uncaughtException(thread, ex);
+        } else {
+            try {
+                Thread.sleep(3000);
+            } catch (InterruptedException e) {
+//                Log.e(TAG, "error : " + e);
+                e.printStackTrace();
+            }
+        }
+
+        // 退出程序
+        ex.printStackTrace();
+        android.os.Process.killProcess(android.os.Process.myPid());
+        System.exit(1);
+    }
+
+    /**
+     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
+     *
+     * @param ex
+     * @return true:如果处理了该异常信息;否则返回false.
+     */
+    private boolean handleException(Throwable ex) {
+        if (ex == null) {
+            return false;
+        }
+        // 使用Toast来显示异常信息
+        new Thread() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                if (mContext != null) {
+                    Toast.makeText(mContext, R.string.program_abnormal, Toast.LENGTH_LONG)
+                            .show();
+                    Looper.loop();
+                }
+            }
+        }.start();
+        // 收集设备参数信息
+        collectDeviceInfo(mContext);
+        // 保存日志文件
+        saveCrashInfo2File(ex);
+        return true;
+    }
+
+    /**
+     * 收集设备参数信息
+     *
+     * @param ctx
+     */
+    public void collectDeviceInfo(Context ctx) {
+        infos.clear();
+        infos.put("===", " PackageInfo ===");
+        try {
+            PackageManager pm = ctx.getPackageManager();
+            PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
+
+            if (pi != null) {
+                String versionName = pi.versionName;
+                String versionCode = pi.versionCode + "";
+                infos.put("versionName", versionName);
+                infos.put("versionCode", versionCode);
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "an error occured when collect package info " + e);
+        }
+
+        infos.put("===", " Build ===");
+        Field[] fields = Build.class.getDeclaredFields();
+        for (Field field : fields) {
+            try {
+                field.setAccessible(true);
+                infos.put(field.getName(), field.get(null).toString());
+                Log.d(TAG, field.getName() + ":" + field.get(null));
+            } catch (Exception e) {
+                Log.e(TAG, "an error occured when collect crash info," + e);
+            }
+        }
+    }
+
+    /**
+     * 保存错误信息到文件中
+     *
+     * @param ex
+     * @return 返回文件名称, 便于将文件传送到服务器
+     */
+    private String saveCrashInfo2File(Throwable ex) {
+
+        String time = formatter.format(new Date());
+        StringBuilder sb = new StringBuilder();
+        sb.append("=== ").append(time).append(" ===\n");
+
+        Writer writer = new StringWriter();
+        PrintWriter printWriter = new PrintWriter(writer);
+        ex.printStackTrace(printWriter);
+//        ex.printStackTrace();
+        Throwable cause = ex.getCause();
+        while (cause != null) {
+            cause.printStackTrace(printWriter);
+            cause = cause.getCause();
+//            cause.printStackTrace();
+        }
+        printWriter.close();
+        String result = writer.toString();
+        sb.append(result);
+        sb.append("\n");
+
+        sb.append("--- DEVICE INFO ---\n");
+        for (Map.Entry<String, String> entry : infos.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+            sb.append(key).append("=").append(value).append("\n");
+        }
+        sb.append("\n\n");
+
+        try {
+            String fileName = "IcLauncher-" + dateFormatDate.format(new Date()) + ".log";
+            if (Environment.getExternalStorageState().equals(
+                    Environment.MEDIA_MOUNTED)) {
+                File dir = new File(Environment.getExternalStorageDirectory().getPath(), "Android/ic/crash/IcLauncher");
+                String path = dir.getPath();
+                if (!dir.exists()) {
+                    dir.mkdirs();
+                }
+                FileOutputStream fos = new FileOutputStream(new File(path, fileName), true);
+                fos.write(sb.toString().getBytes());
+                fos.close();
+            }
+            return fileName;
+        } catch (Exception e) {
+            Log.e(TAG, "an error occured while writing file...," + e);
+        }
+        return null;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/util/IcLog.java b/app/src/main/java/com/ic/ak/launcher/util/IcLog.java
new file mode 100644 (file)
index 0000000..5d8415f
--- /dev/null
@@ -0,0 +1,59 @@
+package com.ic.ak.launcher.util;
+
+import android.util.Log;
+
+import com.ic.ak.launcher.BuildConfig;
+
+/**
+ * @author RyanLee
+ * @date 2018/2/2
+ */
+
+public class IcLog {
+
+    private static final String DOT = ".";
+    private static boolean isDebug = BuildConfig.DEBUG;
+    private static String tagHead = "";
+
+    public static void v(String tag, String msg) {
+        if (isDebug) {
+            Log.v(mergeHeadTag(tag), msg);
+        }
+    }
+
+    public static void d(String tag, String msg) {
+        if (isDebug) {
+            Log.d(mergeHeadTag(tag), msg);
+        }
+    }
+
+    public static void i(String tag, String msg) {
+        if (isDebug) {
+            Log.i(mergeHeadTag(tag), msg);
+        }
+    }
+
+    public static void w(String tag, String msg) {
+        if (isDebug) {
+            Log.w(mergeHeadTag(tag), msg);
+        }
+    }
+
+    public static void e(String tag, String msg,Throwable e) {
+        if (isDebug) {
+            Log.e(mergeHeadTag(tag), msg,e);
+        }
+    }
+
+    public static void setDebug(boolean debug) {
+        isDebug = debug;
+    }
+
+    public static void setLogHead(String head) {
+        tagHead = head + DOT;
+    }
+
+    private static String mergeHeadTag(final String tag) {
+        return tagHead + tag;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/util/SPUtils.java b/app/src/main/java/com/ic/ak/launcher/util/SPUtils.java
new file mode 100644 (file)
index 0000000..4fd370c
--- /dev/null
@@ -0,0 +1,45 @@
+package com.ic.ak.launcher.util;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public class SPUtils {
+
+    private static final String Blood_Heart = "Blood_Heart";
+
+    private static SharedPreferences getSP(Context context) {
+        return context.getSharedPreferences("IcBloodSet", Context.MODE_PRIVATE);
+    }
+
+    public static String getBloodHeartSP(Context context) {
+        return getSP(context).getString(Blood_Heart,"0");
+    }
+
+
+    public static void setBloodHeartSP(Context context,String height) {
+        SharedPreferences.Editor editor = getSP(context).edit();
+        if (editor != null) {
+            editor.putString(Blood_Heart, height);
+            editor.apply();
+        }
+    }
+
+    private static final String Clock_Main= "Clock_Main";
+
+    private static SharedPreferences getClockSP(Context context) {
+        return context.getSharedPreferences("IcClockDial", Context.MODE_PRIVATE);
+    }
+
+    public static int getClockDialSP(Context context) {
+        return getClockSP(context).getInt(Clock_Main, 0);
+    }
+
+
+    public static void setClockDialSP(Context context,int main) {
+        SharedPreferences.Editor editor = getClockSP(context).edit();
+        if (editor != null) {
+            editor.putInt(Clock_Main, main);
+            editor.apply();
+        }
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/util/ServiceUtil.java b/app/src/main/java/com/ic/ak/launcher/util/ServiceUtil.java
new file mode 100644 (file)
index 0000000..ebc4ad2
--- /dev/null
@@ -0,0 +1,46 @@
+package com.ic.ak.launcher.util;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+
+import java.util.List;
+
+public class ServiceUtil {
+
+    public static void startServiceUtil(Context context , String serviceAction, String packageName) {
+        Intent intent = getExplicitIntent(context, new Intent(serviceAction));
+        if(intent != null){
+            intent.setPackage(packageName);
+            context.startService(intent);
+        }
+    }
+
+    public static void bindServiceUtil(Context context , String action, ServiceConnection connection,String pck) {
+        Intent in = getExplicitIntent(context, new Intent(action));
+        if(in != null){
+            in.setPackage(pck);
+            context.bindService(in, connection, 0);
+        }
+    }
+
+    public static void unBindServiceUtil(Context context ,ServiceConnection connection) {
+        context.unbindService(connection);
+    }
+
+    private static Intent getExplicitIntent(Context context, Intent impl) {
+        List<ResolveInfo> resolveInfo = context.getPackageManager().queryIntentServices(impl, 0);
+
+        if (resolveInfo.size() != 1) return null;
+
+        Intent intent = new Intent(impl);
+        ServiceInfo info = resolveInfo.get(0).serviceInfo;
+        if (info == null) return null;
+        intent.setComponent(new ComponentName(info.packageName, info.name));
+
+        return intent;
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/util/ThreadPool.java b/app/src/main/java/com/ic/ak/launcher/util/ThreadPool.java
new file mode 100644 (file)
index 0000000..fa3242f
--- /dev/null
@@ -0,0 +1,17 @@
+package com.ic.ak.launcher.util;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+public class ThreadPool {
+
+    private static ExecutorService poolService;
+
+    public static Future<?> submitRunnablePool(Runnable runnable) {
+        if (poolService == null) {
+            poolService = Executors.newCachedThreadPool();
+        }
+        return poolService.submit(runnable);
+    }
+}
diff --git a/app/src/main/java/com/ic/ak/launcher/widget/MultiRowTextView.java b/app/src/main/java/com/ic/ak/launcher/widget/MultiRowTextView.java
new file mode 100644 (file)
index 0000000..0bfb0f4
--- /dev/null
@@ -0,0 +1,126 @@
+package com.ic.ak.launcher.widget;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.text.Layout;
+import android.text.StaticLayout;
+import android.text.TextPaint;
+import android.util.AttributeSet;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatTextView;
+
+public class MultiRowTextView extends AppCompatTextView {
+
+    private int mLineY;
+    private int mViewWidth;
+
+
+    public MultiRowTextView(Context context) {
+        super(context);
+    }
+
+    public MultiRowTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public MultiRowTextView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right,
+                            int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+    }
+
+    @Override
+    protected void onDraw(Canvas Canvas) {
+        TextPaint paint = getPaint();
+        paint.setColor(getCurrentTextColor());
+        paint.drawableState = getDrawableState();
+        mViewWidth = getMeasuredWidth();
+        String text = getText().toString();
+        mLineY = 0;
+        mLineY += getTextSize();
+        Layout layout = getLayout();
+
+        // layout.getLayout()在4.4.3出现NullPointerException
+        if (layout == null) {
+            return;
+        }
+
+        Paint.FontMetrics fm = paint.getFontMetrics();
+
+        int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
+        textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout
+                .getSpacingAdd());
+        //解决了最后一行文字间距过大的问题
+        for (int i = 0; i < layout.getLineCount(); i++) {
+            int lineStart = layout.getLineStart(i);
+            int lineEnd = layout.getLineEnd(i);
+            float width = StaticLayout.getDesiredWidth(text, lineStart,
+                    lineEnd, getPaint());
+            String line = text.substring(lineStart, lineEnd);
+
+            if(i < layout.getLineCount() - 1) {
+                if (needScale(line)) {
+                    drawScaledText(Canvas, lineStart, line, width);
+                } else {
+                    Canvas.drawText(line, 0, mLineY, paint);
+                }
+            } else {
+                Canvas.drawText(line, 0, mLineY, paint);
+            }
+            mLineY += textHeight;
+        }
+    }
+
+    private void drawScaledText(Canvas Canvas, int lineStart, String line,
+                                float lineWidth) {
+        float x = 0;
+        if (isFirstLineOfParagraph(lineStart, line)) {
+            String blanks = "  ";
+            Canvas.drawText(blanks, x, mLineY, getPaint());
+            float bw = StaticLayout.getDesiredWidth(blanks, getPaint());
+            x += bw;
+
+            line = line.substring(3);
+        }
+
+        int gapCount = line.length() - 1;
+        int i = 0;
+        if (line.length() > 2 && line.charAt(0) == 12288
+                && line.charAt(1) == 12288) {
+            String substring = line.substring(0, 2);
+            float cw = StaticLayout.getDesiredWidth(substring, getPaint());
+            Canvas.drawText(substring, x, mLineY, getPaint());
+            x += cw;
+            i += 2;
+        }
+
+        float d = (mViewWidth - lineWidth) / gapCount;
+        for (; i < line.length(); i++) {
+            String c = String.valueOf(line.charAt(i));
+            float cw = StaticLayout.getDesiredWidth(c, getPaint());
+            Canvas.drawText(c, x, mLineY, getPaint());
+            x += cw + d;
+        }
+    }
+
+    private boolean isFirstLineOfParagraph(int lineStart, String line) {
+        return line.length() > 3 && line.charAt(0) == ' '
+                && line.charAt(1) == ' ';
+    }
+
+    private boolean needScale(String line) {
+        if (line == null || line.length() == 0) {
+            return false;
+        } else {
+            return line.charAt(line.length() - 1) != '\n';
+        }
+    }
+
+}
+
diff --git a/app/src/main/java/com/ic/ak/launcher/widget/WidgetHeadLayout.java b/app/src/main/java/com/ic/ak/launcher/widget/WidgetHeadLayout.java
new file mode 100644 (file)
index 0000000..d88e812
--- /dev/null
@@ -0,0 +1,42 @@
+package com.ic.ak.launcher.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.databinding.BindingAdapter;
+
+import com.ic.ak.launcher.R;
+
+
+public class WidgetHeadLayout extends ConstraintLayout {
+
+    private TextView mTitleView;
+
+    public WidgetHeadLayout(Context context) {
+        this(context,null);
+    }
+
+    public WidgetHeadLayout(Context context, AttributeSet attrs) {
+        this(context,attrs,0);
+    }
+
+    public WidgetHeadLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        View view = View.inflate(context, R.layout.widget_head_layout, this);
+        mTitleView = view.findViewById(R.id.head_title);
+    }
+
+    public void updateHeadTitle(String title){
+        mTitleView.setText(title);
+    }
+
+    @BindingAdapter(value = {"headTitleValue"},requireAll = false)
+    public static void setWidgetHeadLayoutValue(WidgetHeadLayout view,String tile){
+        if(view != null){
+            view.updateHeadTitle(tile);
+        }
+    }
+}
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644 (file)
index 0000000..2b068d1
--- /dev/null
@@ -0,0 +1,30 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                android:endX="85.84757"
+                android:endY="92.4963"
+                android:startX="42.9492"
+                android:startY="49.59793"
+                android:type="linear">
+                <item
+                    android:color="#44000000"
+                    android:offset="0.0" />
+                <item
+                    android:color="#00000000"
+                    android:offset="1.0" />
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillType="nonZero"
+        android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/battery_charging_anim_a9.xml b/app/src/main/res/drawable/battery_charging_anim_a9.xml
new file mode 100644 (file)
index 0000000..7cb116d
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
+    android:oneshot="false">
+    <item
+        android:drawable="@mipmap/a9_battery_0"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/a9_battery_1"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/a9_battery_2"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/a9_battery_3"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/a9_battery_4"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/a9_battery_5"
+        android:duration="800" />
+</animation-list>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/battery_charging_anim_ak.xml b/app/src/main/res/drawable/battery_charging_anim_ak.xml
new file mode 100644 (file)
index 0000000..211f3c9
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
+    android:oneshot="false">
+    <item
+        android:drawable="@mipmap/ak_battery_0"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/ak_battery_1"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/ak_battery_2"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/ak_battery_3"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/ak_battery_4"
+        android:duration="800" />
+    <item
+        android:drawable="@mipmap/ak_battery_5"
+        android:duration="800" />
+</animation-list>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_close_24.xml b/app/src/main/res/drawable/ic_close_24.xml
new file mode 100644 (file)
index 0000000..9c32beb
--- /dev/null
@@ -0,0 +1,5 @@
+<vector android:height="56dp" android:tint="#FFFFFF"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="56dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FFFFFF" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
+</vector>
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644 (file)
index 0000000..07d5da9
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillColor="#3DDC84"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+</vector>
diff --git a/app/src/main/res/drawable/ic_transparent_circle.xml b/app/src/main/res/drawable/ic_transparent_circle.xml
new file mode 100644 (file)
index 0000000..73ee1c7
--- /dev/null
@@ -0,0 +1,5 @@
+<vector android:height="12dp" android:tint="#A7A5A5"
+    android:viewportHeight="24.0" android:viewportWidth="24.0"
+    android:width="12dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#A7A5A5" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z"/>
+</vector>
diff --git a/app/src/main/res/drawable/ic_white_circle.xml b/app/src/main/res/drawable/ic_white_circle.xml
new file mode 100644 (file)
index 0000000..32753d0
--- /dev/null
@@ -0,0 +1,5 @@
+<vector android:height="12dp" android:tint="#FFFFFF"
+    android:viewportHeight="24.0" android:viewportWidth="24.0"
+    android:width="12dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FFFFFF" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z"/>
+</vector>
diff --git a/app/src/main/res/drawable/shape_dialog_notification_bg.xml b/app/src/main/res/drawable/shape_dialog_notification_bg.xml
new file mode 100644 (file)
index 0000000..bc533a6
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 矩形的圆角弧度 -->
+    <corners android:radius="25dp" />
+    <!-- 矩形的填充色 -->
+    <solid android:color="#262626" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shape_dialog_notification_button_close.xml b/app/src/main/res/drawable/shape_dialog_notification_button_close.xml
new file mode 100644 (file)
index 0000000..4ab6d3f
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 矩形的圆角弧度 -->
+    <corners android:radius="15dp" />
+    <!-- 矩形的填充色 -->
+    <solid android:color="#70FFFFFF" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shape_dialog_notification_button_open.xml b/app/src/main/res/drawable/shape_dialog_notification_button_open.xml
new file mode 100644 (file)
index 0000000..c6eff3f
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 矩形的圆角弧度 -->
+    <corners android:radius="15dp" />
+    <!-- 矩形的填充色 -->
+    <solid android:color="#039BE5" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shape_dialog_notification_line.xml b/app/src/main/res/drawable/shape_dialog_notification_line.xml
new file mode 100644 (file)
index 0000000..bc871b5
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 矩形的填充色 -->
+    <solid android:color="#70FFFFFF" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shape_item_bg.xml b/app/src/main/res/drawable/shape_item_bg.xml
new file mode 100644 (file)
index 0000000..2b4f8b6
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 矩形的圆角弧度 -->
+    <corners android:radius="15dp" />
+    <!-- 矩形的填充色 -->
+    <solid android:color="#262626" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shape_main_contacts_bg.xml b/app/src/main/res/drawable/shape_main_contacts_bg.xml
new file mode 100644 (file)
index 0000000..375a8ef
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 矩形的圆角弧度 -->
+    <corners android:radius="30dp" />
+    <!-- 矩形的填充色 -->
+    <solid android:color="#2cadff" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shape_main_week_bg.xml b/app/src/main/res/drawable/shape_main_week_bg.xml
new file mode 100644 (file)
index 0000000..f5ab55b
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 矩形的圆角弧度 -->
+    <corners android:radius="20dp" />
+    <!-- 矩形的填充色 -->
+    <solid android:color="#262626" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shape_notification_button_bg.xml b/app/src/main/res/drawable/shape_notification_button_bg.xml
new file mode 100644 (file)
index 0000000..939dc1a
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 矩形的圆角弧度 -->
+    <corners android:radius="5dp" />
+    <!-- 矩形的填充色 -->
+    <solid android:color="#2cadff" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shape_notification_text_bg.xml b/app/src/main/res/drawable/shape_notification_text_bg.xml
new file mode 100644 (file)
index 0000000..24b81b9
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 矩形的圆角弧度 -->
+    <corners android:radius="20dp" />
+    <!-- 矩形的填充色 -->
+    <solid android:color="#373737" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_a9_main.xml b/app/src/main/res/layout/activity_a9_main.xml
new file mode 100644 (file)
index 0000000..fa14ed8
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".ui.MainActivity">
+
+    <androidx.viewpager2.widget.ViewPager2
+        android:id="@+id/main_vp"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/indicator_rv"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:overScrollMode="never"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.83" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/activity_dialog.xml b/app/src/main/res/layout/activity_dialog.xml
new file mode 100644 (file)
index 0000000..69f3879
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".ui.DialogActivity"/>
\ 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 (file)
index 0000000..49139ca
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".ui.MainActivity">
+
+    <androidx.viewpager2.widget.ViewPager2
+        android:id="@+id/main_vp"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/indicator_rv"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:overScrollMode="never"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.95" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/activity_notification.xml b/app/src/main/res/layout/activity_notification.xml
new file mode 100644 (file)
index 0000000..da34ed4
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".ui.notification.NotificationActivity">
+
+    <TextView
+        android:id="@+id/head_title"
+        style="@style/BaseTextStyle"
+        android:text="@string/notification_title"
+        android:textColor="@color/colorHeadTitle"
+        android:textSize="40sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.1"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.05" />
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="170dp"
+        android:scrollbars="vertical"
+        android:background="@drawable/shape_notification_text_bg"
+        android:layout_marginStart="15dp"
+        android:layout_marginEnd="15dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/head_title"
+        app:layout_constraintVertical_bias="0.0">
+
+        <TextView
+            android:id="@+id/notification_message"
+            style="@style/BaseTextStyle"
+            android:textSize="36sp"/>
+
+    </ScrollView>
+
+    <Button
+        android:id="@+id/notification_bt_ok"
+        android:layout_width="280dp"
+        android:layout_height="70dp"
+        android:background="@drawable/shape_notification_button_bg"
+        android:text="@string/notification_button_str"
+        android:textColor="#FFFFFF"
+        android:textSize="42sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.96" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_notification.xml b/app/src/main/res/layout/dialog_notification.xml
new file mode 100644 (file)
index 0000000..f72a19e
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/dialog_title"
+        style="@style/BaseTextStyle"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="8dp"
+        android:text="@string/dialog_notification_title"
+        android:textColor="#2CADFF"
+        android:textSize="36sp" />
+
+    <com.ic.ak.launcher.widget.MultiRowTextView
+        android:id="@+id/dialog_message"
+        style="@style/BaseTextStyle"
+        android:layout_below="@id/dialog_title"
+        android:layout_centerHorizontal="true"
+        android:layout_marginStart="10dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginEnd="10dp"
+        android:ellipsize="end"
+        android:lines="2"
+        android:maxEms="10"
+        android:textSize="32sp" />
+
+    <View
+        android:id="@+id/dialog_line"
+        android:layout_width="match_parent"
+        android:layout_height="0.5dp"
+        android:layout_below="@id/dialog_message"
+        android:layout_marginTop="10dp"
+        android:background="@drawable/shape_dialog_notification_line" />
+
+    <Button
+        android:id="@+id/dialog_bt_close"
+        android:layout_width="120dp"
+        android:layout_height="60dp"
+        android:layout_below="@id/dialog_line"
+        android:layout_marginStart="15dp"
+        android:layout_marginTop="10dp"
+        android:background="@drawable/shape_dialog_notification_button_close"
+        android:text="@string/dialog_btn_close"
+        android:textColor="@color/colorAppTitle"
+        android:textSize="32sp" />
+
+    <Button
+        android:id="@+id/dialog_bt_open"
+        android:layout_width="120dp"
+        android:layout_height="60dp"
+        android:layout_below="@id/dialog_line"
+        android:layout_alignParentEnd="true"
+        android:layout_marginTop="10dp"
+        android:layout_marginEnd="15dp"
+        android:background="@drawable/shape_dialog_notification_button_open"
+        android:text="@string/dialog_btn_open"
+        android:textColor="@color/colorAppTitle"
+        android:textSize="32sp" />
+</RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_sedentary_alarm.xml b/app/src/main/res/layout/dialog_sedentary_alarm.xml
new file mode 100644 (file)
index 0000000..69a3183
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/sedentary_tv"
+        style="@style/BaseTextStyle"
+        android:drawableTop="@mipmap/ak_sedentary_alarm_main"
+        android:text="@string/sedentary_name"
+        android:textSize="42sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.3"
+        android:drawablePadding="10dp"/>
+
+    <ImageView
+        android:id="@+id/sedentary_close"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@mipmap/ak_sedentary_close"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/sedentary_tv"
+        app:layout_constraintVertical_bias="0.25" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_text_show_a9.xml b/app/src/main/res/layout/dialog_text_show_a9.xml
new file mode 100644 (file)
index 0000000..c89a294
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/message_tips_id"
+       style="@style/BaseTextStyle"
+        android:textSize="28sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"/>
+
+    <ImageView
+        android:id="@+id/slip_bt_close"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_close_24"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.05"
+        app:layout_constraintHorizontal_bias="0.95"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_a9_app.xml b/app/src/main/res/layout/fragment_a9_app.xml
new file mode 100644 (file)
index 0000000..b07c930
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".ui.fragment.AppFragment"
+    android:id="@+id/app_item">
+
+    <ImageView
+        android:id="@+id/app_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.25" />
+
+    <TextView
+        android:id="@+id/app_title"
+        style="@style/BaseTextStyle"
+        android:textSize="@dimen/a9_app_title_text_size"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/app_icon"
+        app:layout_constraintVertical_bias="0.15" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_a9_main.xml b/app/src/main/res/layout/fragment_a9_main.xml
new file mode 100644 (file)
index 0000000..806eb56
--- /dev/null
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".ui.fragment.MainFragment">
+
+    <data>
+
+        <import type="android.graphics.drawable.Drawable" />
+        <import type="android.view.View" />
+
+        <variable
+            name="isNotSim"
+            type="boolean" />
+
+        <variable
+            name="signalIcon"
+            type="Drawable" />
+
+        <variable
+            name="phoneTypeIcon"
+            type="Drawable" />
+
+        <variable
+            name="batteryValue"
+            type="String" />
+
+        <variable
+            name="batteryIcon"
+            type="Drawable" />
+
+        <variable
+            name="timeNumber"
+            type="String" />
+
+        <variable
+            name="week"
+            type="String" />
+
+        <variable
+            name="date"
+            type="String" />
+
+        <variable
+            name="heart"
+            type="String" />
+
+        <variable
+            name="ped"
+            type="String" />
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@{signalIcon}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.243"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.12" />
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@{phoneTypeIcon}"
+            android:visibility="@{isNotSim ? View.GONE:View.VISIBLE}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.38"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.12" />
+
+        <TextView
+            style="@style/BaseTextStyle"
+            android:text="@{batteryValue}"
+            android:textSize="26sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.65"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.12" />
+
+        <ImageView
+            android:id="@+id/battery_iv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@{batteryIcon}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.8"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.12" />
+
+        <TextView
+            android:id="@+id/main_time"
+            style="@style/BaseTextStyle"
+            android:text="@{timeNumber}"
+            android:textColor="#FF9500"
+            android:textSize="72px"
+            android:textStyle="bold"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.4" />
+
+        <TextView
+            style="@style/BaseTextStyle"
+            android:text="@{date}"
+            android:textSize="36sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.65"
+            app:layout_constraintHorizontal_bias="0.3"/>
+
+        <TextView
+            style="@style/BaseTextStyle"
+            android:text="@{week}"
+            android:textSize="36sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.65"
+            app:layout_constraintHorizontal_bias="0.65"/>
+
+        <TextView
+            style="@style/BaseTextStyle"
+            android:text="@{heart}"
+            android:textSize="28sp"
+            android:drawablePadding="2dp"
+            android:drawableStart="@mipmap/a9_heartrate_icon"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.8"
+            app:layout_constraintHorizontal_bias="0.25"/>
+
+
+        <TextView
+            style="@style/BaseTextStyle"
+            android:text="@{ped}"
+            android:textSize="28sp"
+            android:layout_width="120dp"
+            android:drawableStart="@mipmap/a9_pedometer"
+            android:drawablePadding="2dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.8"
+            app:layout_constraintHorizontal_bias="0.75"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
diff --git a/app/src/main/res/layout/fragment_app.xml b/app/src/main/res/layout/fragment_app.xml
new file mode 100644 (file)
index 0000000..1b6a4a5
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".ui.fragment.AppFragment"
+    android:id="@+id/app_item">
+
+    <ImageView
+        android:id="@+id/app_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.3" />
+
+    <TextView
+        android:id="@+id/app_title"
+        style="@style/BaseTextStyle"
+        android:textSize="@dimen/app_title_text_size"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/app_icon"
+        app:layout_constraintVertical_bias="0.15" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_image_battery_low.xml b/app/src/main/res/layout/fragment_image_battery_low.xml
new file mode 100644 (file)
index 0000000..655dffe
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView
+        android:id="@+id/image_tips_image"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@mipmap/low_power_battery"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.43" />
+
+    <ImageView
+        android:id="@+id/slip_bt_close"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_close_24"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.05"
+        app:layout_constraintHorizontal_bias="0.95"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_image_slip.xml b/app/src/main/res/layout/fragment_image_slip.xml
new file mode 100644 (file)
index 0000000..49319d7
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView
+        android:id="@+id/image_tips_image"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@mipmap/ic_band_off"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.73" />
+
+    <ImageView
+        android:id="@+id/slip_bt_close"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_close_24"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.05"
+        app:layout_constraintHorizontal_bias="0.95"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
new file mode 100644 (file)
index 0000000..290a6c8
--- /dev/null
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context=".ui.fragment.MainFragment">
+
+    <data>
+
+        <import type="android.graphics.drawable.Drawable" />
+
+        <import type="android.view.View" />
+
+        <variable
+            name="isNotSim"
+            type="boolean" />
+
+        <variable
+            name="signalIcon"
+            type="Drawable" />
+
+        <variable
+            name="phoneTypeIcon"
+            type="Drawable" />
+
+        <variable
+            name="transportIcon"
+            type="Drawable" />
+
+        <variable
+            name="batteryValue"
+            type="String" />
+
+        <variable
+            name="batteryIcon"
+            type="Drawable" />
+
+        <variable
+            name="timeQuantum"
+            type="String" />
+
+        <variable
+            name="weekDate"
+            type="String" />
+
+        <variable
+            name="timeNumber"
+            type="String" />
+
+        <variable
+            name="timeLunar"
+            type="String" />
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@{signalIcon}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.043"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.023" />
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@{phoneTypeIcon}"
+            android:visibility="@{isNotSim ? View.GONE:View.VISIBLE}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.24"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.023" />
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@{transportIcon}"
+            android:visibility="@{isNotSim ? View.GONE:View.VISIBLE}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.4"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.023" />
+
+        <TextView
+            style="@style/BaseTextStyle"
+            android:text="@{batteryValue}"
+            android:textSize="30sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.75"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.028" />
+
+        <ImageView
+            android:id="@+id/battery_iv"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@{batteryIcon}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.96"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.023" />
+
+        <TextView
+            style="@style/BaseTextStyle"
+            android:text="@{timeQuantum}"
+            android:textSize="30sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.16"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.21" />
+
+        <Button
+            android:layout_width="140dp"
+            android:layout_height="50dp"
+            android:background="@drawable/shape_main_week_bg"
+            android:text="@{weekDate}"
+            android:textColor="#FFFFFF"
+            android:textSize="26sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.9"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.2" />
+
+        <TextView
+            android:id="@+id/main_time"
+            style="@style/BaseTextStyle"
+            android:text="@{timeNumber}"
+            android:textColor="#FF9500"
+            android:textSize="@dimen/main_time_text_size"
+            android:textStyle="bold"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.46" />
+
+        <TextView
+            style="@style/BaseTextStyle"
+            android:text="@string/lunar_calendar"
+            android:textSize="32sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.2"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.69" />
+
+        <TextView
+            style="@style/BaseTextStyle"
+            android:text="@{timeLunar}"
+            android:textSize="32sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.82"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.69" />
+
+        <Button
+            android:id="@+id/bt_family_contacts"
+            android:layout_width="280dp"
+            android:layout_height="70dp"
+            android:background="@drawable/shape_main_contacts_bg"
+            android:text="@string/main_bt_text"
+            android:textColor="#FFFFFF"
+            android:textSize="42sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.96" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
diff --git a/app/src/main/res/layout/item_indicator_layout.xml b/app/src/main/res/layout/item_indicator_layout.xml
new file mode 100644 (file)
index 0000000..c78e0dc
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <data>
+        <variable
+            name="isCheckItem"
+            type="boolean" />
+    </data>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@{isCheckItem ? @drawable/ic_white_circle : @drawable/ic_transparent_circle}" />
+    </LinearLayout>
+</layout>
diff --git a/app/src/main/res/layout/widget_head_layout.xml b/app/src/main/res/layout/widget_head_layout.xml
new file mode 100644 (file)
index 0000000..0b9a2c5
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="60dp">
+
+    <ImageView
+        android:id="@+id/head_image"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@mipmap/ic_head_left_arrows"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.091"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/head_title"
+        style="@style/BaseTextStyle"
+        android:gravity="start"
+        android:textSize="40sp"
+        app:layout_constraintStart_toEndOf="@id/head_image"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintHorizontal_bias="0.1"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        android:textColor="@color/colorHeadTitle"
+        android:layout_marginStart="10dp"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644 (file)
index 0000000..eca70cf
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644 (file)
index 0000000..eca70cf
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..a571e60
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644 (file)
index 0000000..61da551
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_album.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_album.png
new file mode 100644 (file)
index 0000000..01a5923
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_album.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_alipay.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_alipay.png
new file mode 100644 (file)
index 0000000..b863a95
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_alipay.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_app_bind.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_app_bind.png
new file mode 100644 (file)
index 0000000..a5a3f7c
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_app_bind.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_call_records.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_call_records.png
new file mode 100644 (file)
index 0000000..e90dbb4
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_call_records.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_camera.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_camera.png
new file mode 100644 (file)
index 0000000..8731597
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_camera.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_dial.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_dial.png
new file mode 100644 (file)
index 0000000..1140bc9
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_dial.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_healthy.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_healthy.png
new file mode 100644 (file)
index 0000000..f48e787
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_healthy.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_hotline.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_hotline.png
new file mode 100644 (file)
index 0000000..3d63176
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_hotline.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_message.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_message.png
new file mode 100644 (file)
index 0000000..c96dc0e
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_message.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_sedentary.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_sedentary.png
new file mode 100644 (file)
index 0000000..5d45d57
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_sedentary.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_setting.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_setting.png
new file mode 100644 (file)
index 0000000..157d794
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_setting.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_sleep.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_sleep.png
new file mode 100644 (file)
index 0000000..14bee3a
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_sleep.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_app_icon_walk.png b/app/src/main/res/mipmap-ldpi/ak_app_icon_walk.png
new file mode 100644 (file)
index 0000000..cdec6f8
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_app_icon_walk.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_battery_0.png b/app/src/main/res/mipmap-ldpi/ak_battery_0.png
new file mode 100644 (file)
index 0000000..4f0c40e
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_battery_0.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_battery_1.png b/app/src/main/res/mipmap-ldpi/ak_battery_1.png
new file mode 100644 (file)
index 0000000..2ba5cc0
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_battery_1.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_battery_2.png b/app/src/main/res/mipmap-ldpi/ak_battery_2.png
new file mode 100644 (file)
index 0000000..fdf6d6f
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_battery_2.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_battery_3.png b/app/src/main/res/mipmap-ldpi/ak_battery_3.png
new file mode 100644 (file)
index 0000000..19c7c0c
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_battery_3.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_battery_4.png b/app/src/main/res/mipmap-ldpi/ak_battery_4.png
new file mode 100644 (file)
index 0000000..a1d396d
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_battery_4.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_battery_5.png b/app/src/main/res/mipmap-ldpi/ak_battery_5.png
new file mode 100644 (file)
index 0000000..348ef53
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_battery_5.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_data_transport_0.png b/app/src/main/res/mipmap-ldpi/ak_data_transport_0.png
new file mode 100644 (file)
index 0000000..7db5b18
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_data_transport_0.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_data_transport_1.png b/app/src/main/res/mipmap-ldpi/ak_data_transport_1.png
new file mode 100644 (file)
index 0000000..ca38671
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_data_transport_1.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_data_transport_2.png b/app/src/main/res/mipmap-ldpi/ak_data_transport_2.png
new file mode 100644 (file)
index 0000000..acda3a8
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_data_transport_2.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_data_transport_3.png b/app/src/main/res/mipmap-ldpi/ak_data_transport_3.png
new file mode 100644 (file)
index 0000000..bd03153
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_data_transport_3.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_phone_type_2g.png b/app/src/main/res/mipmap-ldpi/ak_phone_type_2g.png
new file mode 100644 (file)
index 0000000..866569b
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_phone_type_2g.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_phone_type_3g.png b/app/src/main/res/mipmap-ldpi/ak_phone_type_3g.png
new file mode 100644 (file)
index 0000000..d45d534
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_phone_type_3g.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_phone_type_4g.png b/app/src/main/res/mipmap-ldpi/ak_phone_type_4g.png
new file mode 100644 (file)
index 0000000..847144a
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_phone_type_4g.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_phone_type_u.png b/app/src/main/res/mipmap-ldpi/ak_phone_type_u.png
new file mode 100644 (file)
index 0000000..785f877
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_phone_type_u.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_sedentary_affirm.png b/app/src/main/res/mipmap-ldpi/ak_sedentary_affirm.png
new file mode 100644 (file)
index 0000000..0713f5e
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_sedentary_affirm.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_sedentary_alarm_main.png b/app/src/main/res/mipmap-ldpi/ak_sedentary_alarm_main.png
new file mode 100644 (file)
index 0000000..35cea6b
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_sedentary_alarm_main.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_sedentary_close.png b/app/src/main/res/mipmap-ldpi/ak_sedentary_close.png
new file mode 100644 (file)
index 0000000..ba2b521
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_sedentary_close.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_signal_0.png b/app/src/main/res/mipmap-ldpi/ak_signal_0.png
new file mode 100644 (file)
index 0000000..6c38c47
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_signal_0.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_signal_1.png b/app/src/main/res/mipmap-ldpi/ak_signal_1.png
new file mode 100644 (file)
index 0000000..ab222b1
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_signal_1.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_signal_2.png b/app/src/main/res/mipmap-ldpi/ak_signal_2.png
new file mode 100644 (file)
index 0000000..07ce173
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_signal_2.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_signal_3.png b/app/src/main/res/mipmap-ldpi/ak_signal_3.png
new file mode 100644 (file)
index 0000000..97d569a
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_signal_3.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_signal_4.png b/app/src/main/res/mipmap-ldpi/ak_signal_4.png
new file mode 100644 (file)
index 0000000..dc01d22
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_signal_4.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ak_signal_x.png b/app/src/main/res/mipmap-ldpi/ak_signal_x.png
new file mode 100644 (file)
index 0000000..c27b208
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ak_signal_x.png differ
diff --git a/app/src/main/res/mipmap-ldpi/ic_head_left_arrows.png b/app/src/main/res/mipmap-ldpi/ic_head_left_arrows.png
new file mode 100644 (file)
index 0000000..acbf105
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/ic_head_left_arrows.png differ
diff --git a/app/src/main/res/mipmap-ldpi/low_power_battery.png b/app/src/main/res/mipmap-ldpi/low_power_battery.png
new file mode 100644 (file)
index 0000000..1bcf586
Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/low_power_battery.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_app_icon_album.png b/app/src/main/res/mipmap-mdpi/a9_app_icon_album.png
new file mode 100644 (file)
index 0000000..01a5923
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_app_icon_album.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_app_icon_camera.png b/app/src/main/res/mipmap-mdpi/a9_app_icon_camera.png
new file mode 100644 (file)
index 0000000..272ee29
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_app_icon_camera.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_app_icon_contacts.png b/app/src/main/res/mipmap-mdpi/a9_app_icon_contacts.png
new file mode 100644 (file)
index 0000000..1008fc5
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_app_icon_contacts.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_app_icon_dial.png b/app/src/main/res/mipmap-mdpi/a9_app_icon_dial.png
new file mode 100644 (file)
index 0000000..54a4c6f
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_app_icon_dial.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_app_icon_healthy.png b/app/src/main/res/mipmap-mdpi/a9_app_icon_healthy.png
new file mode 100644 (file)
index 0000000..fc04047
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_app_icon_healthy.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_app_icon_message.png b/app/src/main/res/mipmap-mdpi/a9_app_icon_message.png
new file mode 100644 (file)
index 0000000..12ba2b1
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_app_icon_message.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_app_icon_setting.png b/app/src/main/res/mipmap-mdpi/a9_app_icon_setting.png
new file mode 100644 (file)
index 0000000..81fee0a
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_app_icon_setting.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_app_icon_temp.png b/app/src/main/res/mipmap-mdpi/a9_app_icon_temp.png
new file mode 100644 (file)
index 0000000..782973c
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_app_icon_temp.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_app_icon_walk.png b/app/src/main/res/mipmap-mdpi/a9_app_icon_walk.png
new file mode 100644 (file)
index 0000000..00ceb31
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_app_icon_walk.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_battery_0.png b/app/src/main/res/mipmap-mdpi/a9_battery_0.png
new file mode 100644 (file)
index 0000000..4f0c40e
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_battery_0.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_battery_1.png b/app/src/main/res/mipmap-mdpi/a9_battery_1.png
new file mode 100644 (file)
index 0000000..2ba5cc0
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_battery_1.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_battery_2.png b/app/src/main/res/mipmap-mdpi/a9_battery_2.png
new file mode 100644 (file)
index 0000000..fdf6d6f
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_battery_2.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_battery_3.png b/app/src/main/res/mipmap-mdpi/a9_battery_3.png
new file mode 100644 (file)
index 0000000..19c7c0c
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_battery_3.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_battery_4.png b/app/src/main/res/mipmap-mdpi/a9_battery_4.png
new file mode 100644 (file)
index 0000000..a1d396d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_battery_4.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_battery_5.png b/app/src/main/res/mipmap-mdpi/a9_battery_5.png
new file mode 100644 (file)
index 0000000..348ef53
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_battery_5.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_heartrate_icon.png b/app/src/main/res/mipmap-mdpi/a9_heartrate_icon.png
new file mode 100644 (file)
index 0000000..eb83864
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_heartrate_icon.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_pedometer.png b/app/src/main/res/mipmap-mdpi/a9_pedometer.png
new file mode 100644 (file)
index 0000000..8881488
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_pedometer.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_phone_type_2g.png b/app/src/main/res/mipmap-mdpi/a9_phone_type_2g.png
new file mode 100644 (file)
index 0000000..866569b
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_phone_type_2g.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_phone_type_3g.png b/app/src/main/res/mipmap-mdpi/a9_phone_type_3g.png
new file mode 100644 (file)
index 0000000..d45d534
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_phone_type_3g.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_phone_type_4g.png b/app/src/main/res/mipmap-mdpi/a9_phone_type_4g.png
new file mode 100644 (file)
index 0000000..847144a
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_phone_type_4g.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_phone_type_u.png b/app/src/main/res/mipmap-mdpi/a9_phone_type_u.png
new file mode 100644 (file)
index 0000000..785f877
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_phone_type_u.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_signal_0.png b/app/src/main/res/mipmap-mdpi/a9_signal_0.png
new file mode 100644 (file)
index 0000000..6c38c47
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_signal_0.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_signal_1.png b/app/src/main/res/mipmap-mdpi/a9_signal_1.png
new file mode 100644 (file)
index 0000000..ab222b1
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_signal_1.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_signal_2.png b/app/src/main/res/mipmap-mdpi/a9_signal_2.png
new file mode 100644 (file)
index 0000000..07ce173
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_signal_2.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_signal_3.png b/app/src/main/res/mipmap-mdpi/a9_signal_3.png
new file mode 100644 (file)
index 0000000..97d569a
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_signal_3.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_signal_4.png b/app/src/main/res/mipmap-mdpi/a9_signal_4.png
new file mode 100644 (file)
index 0000000..dc01d22
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_signal_4.png differ
diff --git a/app/src/main/res/mipmap-mdpi/a9_signal_x.png b/app/src/main/res/mipmap-mdpi/a9_signal_x.png
new file mode 100644 (file)
index 0000000..c27b208
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/a9_signal_x.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ak_signal_nosim.png b/app/src/main/res/mipmap-mdpi/ak_signal_nosim.png
new file mode 100644 (file)
index 0000000..4ab4570
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ak_signal_nosim.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_band_off.png b/app/src/main/res/mipmap-mdpi/ic_band_off.png
new file mode 100644 (file)
index 0000000..46c95dd
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_band_off.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..c41dd28
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644 (file)
index 0000000..db5080a
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..6dba46d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644 (file)
index 0000000..da31a87
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..15ac681
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644 (file)
index 0000000..b216f2d
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..f25a419
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644 (file)
index 0000000..e96783c
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/raw-en/chrg_connect.mp3 b/app/src/main/res/raw-en/chrg_connect.mp3
new file mode 100644 (file)
index 0000000..ba716ad
Binary files /dev/null and b/app/src/main/res/raw-en/chrg_connect.mp3 differ
diff --git a/app/src/main/res/raw-en/chrg_remove.mp3 b/app/src/main/res/raw-en/chrg_remove.mp3
new file mode 100644 (file)
index 0000000..99de4f4
Binary files /dev/null and b/app/src/main/res/raw-en/chrg_remove.mp3 differ
diff --git a/app/src/main/res/raw/a9_antioff.mp3 b/app/src/main/res/raw/a9_antioff.mp3
new file mode 100644 (file)
index 0000000..791a118
Binary files /dev/null and b/app/src/main/res/raw/a9_antioff.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_album.mp3 b/app/src/main/res/raw/ak_app_voice_album.mp3
new file mode 100644 (file)
index 0000000..3ce52d0
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_album.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_bind.mp3 b/app/src/main/res/raw/ak_app_voice_bind.mp3
new file mode 100644 (file)
index 0000000..297876a
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_bind.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_call_records.mp3 b/app/src/main/res/raw/ak_app_voice_call_records.mp3
new file mode 100644 (file)
index 0000000..6a6631c
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_call_records.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_camera.mp3 b/app/src/main/res/raw/ak_app_voice_camera.mp3
new file mode 100644 (file)
index 0000000..be019a5
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_camera.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_dial.mp3 b/app/src/main/res/raw/ak_app_voice_dial.mp3
new file mode 100644 (file)
index 0000000..82d707e
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_dial.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_health.mp3 b/app/src/main/res/raw/ak_app_voice_health.mp3
new file mode 100644 (file)
index 0000000..a6073ed
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_health.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_living_home.mp3 b/app/src/main/res/raw/ak_app_voice_living_home.mp3
new file mode 100644 (file)
index 0000000..fe4b42d
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_living_home.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_message.mp3 b/app/src/main/res/raw/ak_app_voice_message.mp3
new file mode 100644 (file)
index 0000000..b4c5fa6
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_message.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_ped.mp3 b/app/src/main/res/raw/ak_app_voice_ped.mp3
new file mode 100644 (file)
index 0000000..13d5fbe
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_ped.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_sedentary.mp3 b/app/src/main/res/raw/ak_app_voice_sedentary.mp3
new file mode 100644 (file)
index 0000000..011cf63
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_sedentary.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_setting.mp3 b/app/src/main/res/raw/ak_app_voice_setting.mp3
new file mode 100644 (file)
index 0000000..fe2e042
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_setting.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_sleep.mp3 b/app/src/main/res/raw/ak_app_voice_sleep.mp3
new file mode 100644 (file)
index 0000000..3844234
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_sleep.mp3 differ
diff --git a/app/src/main/res/raw/ak_app_voice_zfb.mp3 b/app/src/main/res/raw/ak_app_voice_zfb.mp3
new file mode 100644 (file)
index 0000000..35e885c
Binary files /dev/null and b/app/src/main/res/raw/ak_app_voice_zfb.mp3 differ
diff --git a/app/src/main/res/raw/chrg_complete.mp3 b/app/src/main/res/raw/chrg_complete.mp3
new file mode 100644 (file)
index 0000000..c56ac5a
Binary files /dev/null and b/app/src/main/res/raw/chrg_complete.mp3 differ
diff --git a/app/src/main/res/raw/chrg_connect.mp3 b/app/src/main/res/raw/chrg_connect.mp3
new file mode 100644 (file)
index 0000000..ba5c0ce
Binary files /dev/null and b/app/src/main/res/raw/chrg_connect.mp3 differ
diff --git a/app/src/main/res/raw/chrg_remove.mp3 b/app/src/main/res/raw/chrg_remove.mp3
new file mode 100644 (file)
index 0000000..4a91c17
Binary files /dev/null and b/app/src/main/res/raw/chrg_remove.mp3 differ
diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml
new file mode 100644 (file)
index 0000000..4fad51a
--- /dev/null
@@ -0,0 +1,62 @@
+<resources>
+    <string name="app_name">IcAkLauncher</string>
+    <string name="hello_blank_fragment">Hello blank fragment</string>
+
+    <string name="app_title_living_home">居家热线</string>
+    <string name="app_title_dial">拨号</string>
+    <string name="app_title_message">短信</string>
+    <string name="app_title_pedometer">计步器</string>
+    <string name="app_title_health">健康</string>
+    <string name="app_title_sleep">睡眠</string>
+    <string name="app_title_sedentary">久坐提醒</string>
+    <string name="app_title_camera">相机</string>
+    <string name="app_title_album">相册</string>
+    <string name="app_title_alipay">支付宝</string>
+    <string name="app_title_app_bind">App绑定</string>
+    <string name="app_title_setting">设置</string>
+
+
+    <string name="a9_app_title_message">Message</string>
+    <string name="a9_app_title_health">Health</string>
+    <string name="a9_app_title_temperature">TEMP</string>
+    <string name="a9_app_title_camera">Camera</string>
+    <string name="a9_app_title_album">Album</string>
+    <string name="a9_app_title_pedometer">Sports</string>
+    <string name="a9_app_title_contacts">Contacts</string>
+    <string name="a9_app_title_dial">Dial</string>
+    <string name="a9_app_title_setting">Setting</string>
+
+
+    <string name="lunar_calendar">农历</string>
+    <string name="main_bt_text">联系家人</string>
+
+    <string name="lunar_intercalary">闰</string>
+    <string name="lunar_show_str">%1$s%2$s月%3$s</string>
+
+    <string name="time_wee_hours">凌晨了~</string>
+    <string name="time_morning">早上好~</string>
+    <string name="time_am">上午好~</string>
+    <string name="time_noon">中午好~</string>
+    <string name="time_pm">下午好~</string>
+    <string name="time_at_dusk">傍晚好~</string>
+    <string name="time_evening">晚上好~</string>
+    <string name="time_night">深夜了~</string>
+
+    <string name="time_date_week_str">%1$s号 %2$s</string>
+
+
+    <string name="notification_title">通知消息</string>
+    <string name="notification_button_str">知道了</string>
+
+    <string name="program_abnormal">Sorry, the program has an exception, will exit</string>
+    <string name="tips_start_activity">Failed to start application</string>
+
+    <dimen name="app_title_text_size">52sp</dimen>
+    <dimen name="a9_app_title_text_size">38sp</dimen>
+    <dimen name="app_next_item_visible">26dp</dimen>
+    <dimen name="app_current_item_horizontal_margin">42dp</dimen>
+
+    <dimen name="main_time_text_size">82px</dimen>
+
+    <dimen name="dialog_text_size">28sp</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
new file mode 100644 (file)
index 0000000..c796138
--- /dev/null
@@ -0,0 +1,57 @@
+<resources>
+    <string name="app_name">IcAkLauncher</string>
+
+    <string name="app_title_living_home">居家热线</string>
+    <string name="app_title_dial">拨号</string>
+    <string name="app_title_message">短信</string>
+    <string name="app_title_pedometer">计步器</string>
+    <string name="app_title_health">健康</string>
+    <string name="app_title_sleep">睡眠</string>
+    <string name="app_title_sedentary">久坐提醒</string>
+    <string name="app_title_camera">相机</string>
+    <string name="app_title_album">相册</string>
+    <string name="app_title_alipay">支付宝</string>
+    <string name="app_title_app_bind">App绑定</string>
+    <string name="app_title_setting">设置</string>
+
+    <string name="a9_app_title_message">短信</string>
+    <string name="a9_app_title_health">健康</string>
+    <string name="a9_app_title_temperature">体温</string>
+    <string name="a9_app_title_camera">相机</string>
+    <string name="a9_app_title_album">相册</string>
+    <string name="a9_app_title_pedometer">运动</string>
+    <string name="a9_app_title_contacts">联系人</string>
+    <string name="a9_app_title_dial">拨号</string>
+    <string name="a9_app_title_setting">设置</string>
+
+    <string name="lunar_calendar">农历</string>
+    <string name="main_bt_text">联系家人</string>
+
+    <string name="lunar_intercalary">闰</string>
+    <string name="lunar_show_str">%1$s%2$s月%3$s</string>
+
+    <string name="time_wee_hours">凌晨了~</string>
+    <string name="time_morning">早上好~</string>
+    <string name="time_am">上午好~</string>
+    <string name="time_noon">中午好~</string>
+    <string name="time_pm">下午好~</string>
+    <string name="time_at_dusk">傍晚好~</string>
+    <string name="time_evening">晚上好~</string>
+    <string name="time_night">深夜了~</string>
+
+    <string name="time_date_week_str">%1$s号 %2$s</string>
+
+
+    <string name="notification_title">通知消息</string>
+    <string name="notification_button_str">知道了</string>
+
+    <string name="program_abnormal">很抱歉,程序出现异常,即将退出</string>
+    <string name="tips_start_activity">启动应用失败</string>
+
+    <dimen name="app_title_text_size">52sp</dimen>
+    <dimen name="a9_app_title_text_size">38sp</dimen>
+    <dimen name="app_next_item_visible">26dp</dimen>
+    <dimen name="app_current_item_horizontal_margin">42dp</dimen>
+
+    <dimen name="main_time_text_size">82px</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644 (file)
index 0000000..3742d6a
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#6200EE</color>
+    <color name="colorPrimaryDark">#3700B3</color>
+    <color name="colorAccent">#03DAC5</color>
+
+    <color name="colorMainBackground">#000000</color>
+    <color name="colorAppTitle">#FFFFFF</color>
+    <color name="colorHeadTitle">#2CADFF</color>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..f489169
--- /dev/null
@@ -0,0 +1,67 @@
+<resources>
+    <string name="app_name">IcAkLauncher</string>
+    <string name="hello_blank_fragment">Hello blank fragment</string>
+
+    <string name="app_title_living_home">居家热线</string>
+    <string name="app_title_dial">拨号</string>
+    <string name="app_title_call_records">通话记录</string>
+    <string name="app_title_message">短信</string>
+    <string name="app_title_pedometer">计步器</string>
+    <string name="app_title_health">健康</string>
+    <string name="app_title_sleep">睡眠</string>
+    <string name="app_title_sedentary">久坐提醒</string>
+    <string name="app_title_camera">相机</string>
+    <string name="app_title_album">相册</string>
+    <string name="app_title_alipay">支付宝</string>
+    <string name="app_title_app_bind">App绑定</string>
+    <string name="app_title_setting">设置</string>
+
+    <string name="a9_app_title_message">短信</string>
+    <string name="a9_app_title_health">健康</string>
+    <string name="a9_app_title_temperature">体温</string>
+    <string name="a9_app_title_camera">相机</string>
+    <string name="a9_app_title_album">相册</string>
+    <string name="a9_app_title_pedometer">运动</string>
+    <string name="a9_app_title_contacts">联系人</string>
+    <string name="a9_app_title_dial">拨号</string>
+    <string name="a9_app_title_setting">设置</string>
+
+    <string name="lunar_calendar">农历</string>
+    <string name="main_bt_text">联系家人</string>
+
+    <string name="lunar_intercalary">闰</string>
+    <string name="lunar_show_str">%1$s%2$s月%3$s</string>
+
+    <string name="time_wee_hours">凌晨了~</string>
+    <string name="time_morning">早上好~</string>
+    <string name="time_am">上午好~</string>
+    <string name="time_noon">中午好~</string>
+    <string name="time_pm">下午好~</string>
+    <string name="time_at_dusk">傍晚好~</string>
+    <string name="time_evening">晚上好~</string>
+    <string name="time_night">深夜了~</string>
+
+    <string name="time_date_week_str">%1$s号 %2$s</string>
+
+
+    <string name="notification_title">通知消息</string>
+    <string name="notification_button_str">知道了</string>
+
+    <string name="program_abnormal">很抱歉,程序出现异常,即将退出</string>
+    <string name="tips_start_activity">启动应用失败</string>
+
+    <string name="dialog_notification_title">消息提醒</string>
+    <string name="dialog_btn_close">关闭</string>
+    <string name="dialog_btn_open">阅读</string>
+
+    <string name="sedentary_name">久坐提醒</string>
+
+    <dimen name="app_title_text_size">52sp</dimen>
+    <dimen name="a9_app_title_text_size">38sp</dimen>
+    <dimen name="app_next_item_visible">26dp</dimen>
+    <dimen name="app_current_item_horizontal_margin">42dp</dimen>
+
+    <dimen name="main_time_text_size">82px</dimen>
+
+    <dimen name="dialog_text_size">28sp</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..3f93127
--- /dev/null
@@ -0,0 +1,53 @@
+<resources>
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+        <item name="android:windowBackground">@color/colorMainBackground</item>
+    </style>
+
+    <style name="BaseTextStyle">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/colorAppTitle</item>
+        <item name="android:textSize">@dimen/app_title_text_size</item>
+        <item name="android:includeFontPadding">false</item>
+    </style>
+
+    <style name="TipsDialog" parent="android:Theme.Holo.Light.Dialog">
+        <item name="android:windowBackground">#000000</item>
+        <item name="android:windowFrame">@null</item>
+        <item name="android:backgroundDimEnabled">true</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+    </style>
+
+    <style name="NotificationDialog" parent="android:Theme.Holo.Light.Dialog">
+        <item name="android:windowBackground">@drawable/shape_dialog_notification_bg</item>
+        <item name="android:windowFrame">@null</item>
+        <item name="android:backgroundDimEnabled">true</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowIsFloating">true</item>
+    </style>
+
+    <style name="DialogActivityStyle" parent="Theme.AppCompat.Light.NoActionBar">
+        <item name="android:windowFullscreen">true</item>
+        <item name="windowNoTitle">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <!-- Note that we use the base animation style here (that is no
+             animations) because we really have no idea how this kind of
+             activity will be used. -->
+        <item name="android:windowAnimationStyle">@android:style/Animation</item>
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/app/src/test/java/com/ic/ak/launcher/ExampleUnitTest.java b/app/src/test/java/com/ic/ak/launcher/ExampleUnitTest.java
new file mode 100644 (file)
index 0000000..4b87dee
--- /dev/null
@@ -0,0 +1,17 @@
+package com.ic.ak.launcher;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+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 (file)
index 0000000..c732b10
--- /dev/null
@@ -0,0 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+
+    dependencies {
+        classpath 'com.android.tools.build:gradle:4.0.1'
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644 (file)
index 0000000..c52ac9b
--- /dev/null
@@ -0,0 +1,19 @@
+# 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=-Xmx2048m
+# 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
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644 (file)
index 0000000..f6b961f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644 (file)
index 0000000..698857a
--- /dev/null
@@ -0,0 +1,6 @@
+#Tue Jun 30 11:40:42 CST 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
diff --git a/gradlew b/gradlew
new file mode 100644 (file)
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 (file)
index 0000000..f955316
--- /dev/null
@@ -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 (file)
index 0000000..491af94
--- /dev/null
@@ -0,0 +1,2 @@
+include ':app'
+rootProject.name = "IcAkLauncher"
\ No newline at end of file