From: kfl_614 Date: Wed, 19 Aug 2020 07:14:03 +0000 (+0800) Subject: AK\A9 Launcher X-Git-Url: http://git.snicker.com.cn/Users/apple/Desktop/static/gitweb.css?a=commitdiff_plain;h=9a316e1dcb2cc5469682a8b1b7981c7899786f85;p=aklauncher.git AK\A9 Launcher --- 9a316e1dcb2cc5469682a8b1b7981c7899786f85 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx diff --git a/.idea/$PROJECT_FILE$ b/.idea/$PROJECT_FILE$ new file mode 100644 index 0000000..58b7e3e --- /dev/null +++ b/.idea/$PROJECT_FILE$ @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..c820ab9 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..a5f05cd --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..fdba094 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/qaplug_profiles.xml b/.idea/qaplug_profiles.xml new file mode 100644 index 0000000..3dfd21f --- /dev/null +++ b/.idea/qaplug_profiles.xml @@ -0,0 +1,465 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -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 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 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 index 0000000..6a30b8a --- /dev/null +++ b/app/IcA9Launcher/release/output-metadata.json @@ -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 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 index 0000000..efeab5b --- /dev/null +++ b/app/IcAkLauncher/release/output-metadata.json @@ -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 index 0000000..69ae875 --- /dev/null +++ b/app/build.gradle @@ -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 index 0000000..2fcfd84 --- /dev/null +++ b/app/proguard-rules.pro @@ -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 ; +} + +# 保留本地native方法不被混淆 +-keepclasseswithmembernames class * { + native ; +} + +# 保留在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 (android.content.Context); + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (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 ; + !private ; + !private ; + 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 ; +} +-keep enum org.greenrobot.eventbus.ThreadMode { *; } + +# And if you use AsyncExecutor: +-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { + (java.lang.Throwable); +} + +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep class * extends com.bumptech.glide.module.AppGlideModule { + (...); +} +-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 index 0000000..9907abb --- /dev/null +++ b/app/src/androidTest/java/com/ic/ak/launcher/ExampleInstrumentedTest.java @@ -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 Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.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 index 0000000..decdb91 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 index 0000000..bc7c011 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/LauncherApp.java @@ -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 index 0000000..4334891 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/app/AppConfig.java @@ -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 index 0000000..d63603d --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/app/AppDispose.java @@ -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 index 0000000..7e2c31d --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/app/AppItem.java @@ -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 CREATOR + = new Parcelable.Creator() { + 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 index 0000000..7b21e70 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/battery/BatteryConnectStateEvent.java @@ -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 index 0000000..ff390a5 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/battery/BatteryDispose.java @@ -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 mBatteryValueLiveData; + private MutableLiveData mBatteryChargingLiveData; + private MutableLiveData mBatteryResIDLiveData; + + public LiveData getBatteryChargingLiveData() { + return mBatteryChargingLiveData; + } + + public LiveData getBatteryResIDLiveData() { + return mBatteryResIDLiveData; + } + + public MutableLiveData 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 index 0000000..65b08a4 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/hardware/HardwareDispose.java @@ -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 mObsHardwareHeart; + private MutableLiveData mObsHardwarePed; + + public HardwareDispose() { + mObsHardwareHeart = new MediatorLiveData<>(); + mObsHardwarePed = new MediatorLiveData<>(); + } + + public MutableLiveData getObsHardwareHeart() { + return mObsHardwareHeart; + } + + public MutableLiveData 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 index 0000000..1fda4cd --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/phone/CallPhone.java @@ -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 index 0000000..ff1448e --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/phone/LoopThread.java @@ -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 index 0000000..582599b --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/phone/PhoneDispose.java @@ -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 mTypeID; + private MutableLiveData mSignalID; + private MutableLiveData mTransportID; + private MutableLiveData 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 getTypeID() { + return mTypeID; + } + + public LiveData getSignalID() { + return mSignalID; + } + + public LiveData getTransportID() { + return mTransportID; + } + + public LiveData 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 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 index 0000000..356f493 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/play/SoundPlayUtils.java @@ -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 index 0000000..21bd408 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/data/time/TimeDispose.java @@ -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 mTimeQuantumLiveData; + private MutableLiveData> mWeekDateLiveData; + private MutableLiveData mTimeLiveData; + private MutableLiveData> mLunarCalendarLiveData; + + private MutableLiveData mObsTime; + private MutableLiveData mObsYear; + private MutableLiveData 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 getTimeQuantumLiveData() { + return mTimeQuantumLiveData; + } + + public LiveData> getWeekDateLiveData() { + return mWeekDateLiveData; + } + + public LiveData getTimeLiveData() { + return mTimeLiveData; + } + + public LiveData> getLunarCalendarLiveData() { + return mLunarCalendarLiveData; + } + + public MutableLiveData getObsTime() { + return mObsTime; + } + + public MutableLiveData getObsYear() { + return mObsYear; + } + + public MutableLiveData 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 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 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 index 0000000..494f059 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/DialogActivity.java @@ -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 index 0000000..26d665b --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/FragmentAdapter.java @@ -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 index 0000000..52201a2 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/IndicatorAdapter.java @@ -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 { + + 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 index 0000000..102a1f8 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/MainActivity.java @@ -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 index 0000000..29d6298 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/BatteryLowFragment.java @@ -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 index 0000000..98780d4 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/BatteryLowManage.java @@ -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 index 0000000..b2c6d20 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/DialogDismissEvent.java @@ -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 index 0000000..8a6bb91 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/NotificationDialogFragment.java @@ -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 index 0000000..5c21f72 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/NotificationDialogManage.java @@ -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 index 0000000..0324aa8 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/SedentaryAlarmDialogFragment.java @@ -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 index 0000000..1d9ddfb --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/SedentaryDialogManage.java @@ -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 index 0000000..52000a0 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/SlipTipsFragment.java @@ -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 index 0000000..0c80bc6 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/SlipTipsManage.java @@ -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 index 0000000..289e447 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/TextShowDialogFragment.java @@ -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 index 0000000..19013d9 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/dialog/TextShowDialogManage.java @@ -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 index 0000000..7909e11 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/fragment/AppFragment.java @@ -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 index 0000000..79cc597 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/fragment/AppVoicePlayEvent.java @@ -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 index 0000000..83ff99e --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainA9Fragment.java @@ -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 index 0000000..44af851 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainA9ViewModel.java @@ -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 create(@NonNull Class modelClass) { + return (T) new MainA9ViewModel(app.getTimeDispose(),app.getBatteryDispose(),app.getPhoneDispose(),app.getHardwareDispose()); + } + } + + public LiveData getObservableTime() { + return timeDispose.getObsTime(); + } + + public LiveData getObservableWeek() { + return timeDispose.getObsWeek(); + } + + public LiveData getObservableYear() { + return timeDispose.getObsYear(); + } + + public LiveData getTypeID() { + return phoneDispose.getTypeID(); + } + + public LiveData getSignalID() { + return phoneDispose.getSignalID(); + } + + public LiveData getSimCardState() { + return phoneDispose.getSimCardState(); + } + + public void resumeQueryThread() { + phoneDispose.resumeQueryThread(); + } + + public void pauseQueryThread() { + phoneDispose.pauseQueryThread(); + } + + public LiveData getBatteryChargingLiveData() { + return batteryDispose.getBatteryChargingLiveData(); + } + + public LiveData getBatteryResIDLiveData() { + return batteryDispose.getBatteryResIDLiveData(); + } + + public MutableLiveData getBatteryValueLiveData() { + return batteryDispose.getBatteryValueLiveData(); + } + + public LiveData getObservableHardwareHeart() { + return hardwareDispose.getObsHardwareHeart(); + } + + public LiveData 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 index 0000000..082dbd1 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainFragment.java @@ -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 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 index 0000000..3562671 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/fragment/MainViewModel.java @@ -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 create(@NonNull Class modelClass) { + return (T) new MainViewModel(app.getTimeDispose(),app.getBatteryDispose(),app.getPhoneDispose()); + } + } + + public LiveData getTimeQuantumLiveData() { + return timeDispose.getTimeQuantumLiveData(); + } + + public LiveData> getWeekDateLiveData() { + return timeDispose.getWeekDateLiveData(); + } + + public LiveData getTimeLiveData() { + return timeDispose.getTimeLiveData(); + } + + public LiveData> getLunarCalendarLiveData() { + return timeDispose.getLunarCalendarLiveData(); + } + + public LiveData getBatteryChargingLiveData() { + return batteryDispose.getBatteryChargingLiveData(); + } + + public LiveData getBatteryResIDLiveData() { + return batteryDispose.getBatteryResIDLiveData(); + } + + public MutableLiveData getBatteryValueLiveData() { + return batteryDispose.getBatteryValueLiveData(); + } + + + public LiveData getTypeID() { + return phoneDispose.getTypeID(); + } + + public LiveData getSignalID() { + return phoneDispose.getSignalID(); + } + + public LiveData getTransportID() { + return phoneDispose.getTransportID(); + } + + public LiveData 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 index 0000000..f8a5786 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/ui/notification/NotificationActivity.java @@ -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 index 0000000..6d39a71 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/util/CrashHandler.java @@ -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 infos = new HashMap(); + // 用于格式化日期,作为日志文件名的一部分 + 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 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 index 0000000..5d8415f --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/util/IcLog.java @@ -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 index 0000000..4fd370c --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/util/SPUtils.java @@ -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 index 0000000..ebc4ad2 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/util/ServiceUtil.java @@ -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 = 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 index 0000000..fa3242f --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/util/ThreadPool.java @@ -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 index 0000000..0bfb0f4 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/widget/MultiRowTextView.java @@ -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 index 0000000..d88e812 --- /dev/null +++ b/app/src/main/java/com/ic/ak/launcher/widget/WidgetHeadLayout.java @@ -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 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/battery_charging_anim_a9.xml b/app/src/main/res/drawable/battery_charging_anim_a9.xml new file mode 100644 index 0000000..7cb116d --- /dev/null +++ b/app/src/main/res/drawable/battery_charging_anim_a9.xml @@ -0,0 +1,22 @@ + + + + + + + + + \ 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 index 0000000..211f3c9 --- /dev/null +++ b/app/src/main/res/drawable/battery_charging_anim_ak.xml @@ -0,0 +1,22 @@ + + + + + + + + + \ 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 index 0000000..9c32beb --- /dev/null +++ b/app/src/main/res/drawable/ic_close_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_transparent_circle.xml b/app/src/main/res/drawable/ic_transparent_circle.xml new file mode 100644 index 0000000..73ee1c7 --- /dev/null +++ b/app/src/main/res/drawable/ic_transparent_circle.xml @@ -0,0 +1,5 @@ + + + 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 index 0000000..32753d0 --- /dev/null +++ b/app/src/main/res/drawable/ic_white_circle.xml @@ -0,0 +1,5 @@ + + + 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 index 0000000..bc533a6 --- /dev/null +++ b/app/src/main/res/drawable/shape_dialog_notification_bg.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 index 0000000..4ab6d3f --- /dev/null +++ b/app/src/main/res/drawable/shape_dialog_notification_button_close.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 index 0000000..c6eff3f --- /dev/null +++ b/app/src/main/res/drawable/shape_dialog_notification_button_open.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 index 0000000..bc871b5 --- /dev/null +++ b/app/src/main/res/drawable/shape_dialog_notification_line.xml @@ -0,0 +1,6 @@ + + + + + \ 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 index 0000000..2b4f8b6 --- /dev/null +++ b/app/src/main/res/drawable/shape_item_bg.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 index 0000000..375a8ef --- /dev/null +++ b/app/src/main/res/drawable/shape_main_contacts_bg.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 index 0000000..f5ab55b --- /dev/null +++ b/app/src/main/res/drawable/shape_main_week_bg.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 index 0000000..939dc1a --- /dev/null +++ b/app/src/main/res/drawable/shape_notification_button_bg.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 index 0000000..24b81b9 --- /dev/null +++ b/app/src/main/res/drawable/shape_notification_text_bg.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 index 0000000..fa14ed8 --- /dev/null +++ b/app/src/main/res/layout/activity_a9_main.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/app/src/main/res/layout/activity_dialog.xml b/app/src/main/res/layout/activity_dialog.xml new file mode 100644 index 0000000..69f3879 --- /dev/null +++ b/app/src/main/res/layout/activity_dialog.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..49139ca --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/app/src/main/res/layout/activity_notification.xml b/app/src/main/res/layout/activity_notification.xml new file mode 100644 index 0000000..da34ed4 --- /dev/null +++ b/app/src/main/res/layout/activity_notification.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + +