From e46379d65b5ca6f3b11ef25f6b625446aaf9b5d6 Mon Sep 17 00:00:00 2001 From: kfl_614 Date: Sun, 29 Mar 2020 18:36:39 +0800 Subject: [PATCH] =?utf8?q?1.=E6=B7=BB=E5=8A=A0=E5=A4=9A=E8=A1=A8=E7=9B=98?= =?utf8?q?=E9=80=89=E6=8B=A9=202.=E6=B7=BB=E5=8A=A0=E4=BD=8E=E7=94=B5?= =?utf8?q?=E9=87=8F=E6=A8=A1=E5=BC=8F=203.=E4=BC=98=E5=8C=96=E6=A1=86?= =?utf8?q?=E6=9E=B6=E7=BB=93=E6=9E=84=E3=80=82=E9=98=B2=E6=AD=A2=E5=9C=A8?= =?utf8?q?=E5=88=87=E6=8D=A2Fragment=E8=A3=85=E5=A4=A9=E5=BC=82=E5=B8=B8?= =?utf8?q?=E3=80=82=204.=E4=BF=AE=E5=A4=8DAPP=E5=88=97=E8=A1=A8=E6=8C=87?= =?utf8?q?=E7=A4=BA=E5=99=A8=E7=9A=84=E9=97=B4=E8=B7=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: kfl_614 --- app/EQC_G5.jks | Bin 0 -> 4688 bytes app/build.gradle | 6 +- app/src/main/AndroidManifest.xml | 14 +- .../java/com/ic/launcher/FragmentManage.java | 203 +++++++++++++++++ .../ic/launcher/IcLauncherApplication.java | 7 +- .../java/com/ic/launcher/MainActivity.java | 168 +++++++------- .../com/ic/launcher/SelectDialActivity.java | 33 +++ .../launcher/adapter/WatchPreviewAdapter.java | 62 ++++++ .../ic/launcher/configure/l02/L02AppInfo.java | 5 + .../ic/launcher/configure/l02/L02Icon.java | 11 + .../ic/launcher/entity/ClockDialEntity.java | 39 ++++ .../ic/launcher/fragment/AppListFragment.java | 75 +++---- .../ic/launcher/fragment/BaseFragment.java | 91 ++++++++ .../ic/launcher/fragment/L02MainFragment.java | 209 +++++++++--------- .../fragment/LowPowerModeFragment.java | 121 ++++++++++ .../fragment/SelectClockDialFragment.java | 99 +++++++++ .../fragment/clock/Clock12DialFragment.java | 53 +++++ .../fragment/clock/Clock6DialFragment.java | 50 +++++ .../fragment/l02/L02StatusBarFragment.java | 63 ------ .../fragment/l02/L02WatchFragment.java | 83 ------- .../listener/ILowPowerCallPhoneListener.java | 5 + .../listener/ILowPowerStateListener.java | 5 + .../listener/ISelectDialListener.java | 7 + .../ic/launcher/mode/AnalogColorModel.java | 48 ++++ .../mode/{AppListModel.java => AppModel.java} | 53 +++-- .../java/com/ic/launcher/mode/BaseModel.java | 73 ++++++ .../com/ic/launcher/mode/L02MainModel.java | 165 +++++++------- .../com/ic/launcher/mode/LowPowerModel.java | 66 ++++++ .../launcher/presenter/AppListPresenter.java | 3 +- .../launcher/presenter/BatteryPresenter.java | 141 +++++++++--- .../launcher/presenter/HardwarePresenter.java | 40 ++-- .../presenter/PhoneStatePresenter.java | 58 ++--- .../ic/launcher/presenter/PresenterCycle.java | 16 ++ .../launcher/presenter/QueryPhoneState.java | 2 +- .../ic/launcher/presenter/QueryThread.java | 5 +- .../launcher/presenter/TimeDatePresenter.java | 197 ++++++++++++----- .../java/com/ic/launcher/util/SPUtils.java | 21 +- .../ic/launcher/widget/ClockDrawableView.java | 122 ++++++++++ .../ic/launcher/widget/ClockWatchView.java | 135 ----------- .../launcher/widget/WidgetTimeImageView.java | 31 ++- .../main/res/layout/activity_select_dial.xml | 8 + app/src/main/res/layout/fragment_app_list.xml | 2 +- .../res/layout/fragment_clock_12_dial.xml | 31 +++ .../main/res/layout/fragment_clock_6_dial.xml | 30 +++ app/src/main/res/layout/fragment_l02_main.xml | 171 ++++++++++++-- .../res/layout/fragment_l02_status_bar.xml | 64 ------ .../main/res/layout/fragment_l02_watch.xml | 94 -------- .../res/layout/fragment_low_power_mode.xml | 72 ++++++ .../res/layout/fragment_select_clock_dial.xml | 9 + .../main/res/layout/item_watch_preview.xml | 27 +++ .../res/mipmap-ldpi/clock12_dial_preview.png | Bin 0 -> 8804 bytes .../res/mipmap-ldpi/clock6_dial_preview.png | Bin 0 -> 9230 bytes .../res/mipmap-ldpi/clockl02_dial_preview.png | Bin 0 -> 15477 bytes app/src/main/res/mipmap-mdpi/clock12_dial.png | Bin 0 -> 4972 bytes .../main/res/mipmap-mdpi/clock12_hand_cap.png | Bin 0 -> 1249 bytes .../res/mipmap-mdpi/clock12_hand_hour.png | Bin 0 -> 2030 bytes .../res/mipmap-mdpi/clock12_hand_minute.png | Bin 0 -> 1969 bytes .../res/mipmap-mdpi/clock12_hand_second.png | Bin 0 -> 1892 bytes app/src/main/res/mipmap-mdpi/clock6_dial.png | Bin 0 -> 6182 bytes .../main/res/mipmap-mdpi/clock6_hand_cap.png | Bin 0 -> 1199 bytes .../main/res/mipmap-mdpi/clock6_hand_hour.png | Bin 0 -> 1312 bytes .../res/mipmap-mdpi/clock6_hand_minute.png | Bin 0 -> 1112 bytes .../res/mipmap-mdpi/clock6_hand_second.png | Bin 0 -> 1079 bytes .../res/mipmap-mdpi/low_power_battery.png | Bin 0 -> 2013 bytes .../main/res/mipmap-mdpi/low_power_dial.png | Bin 0 -> 2467 bytes .../main/res/mipmap-mdpi/qs_background.png | Bin 0 -> 9876 bytes app/src/main/res/values/attr.xml | 11 +- app/src/main/res/values/dimens.xml | 3 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 8 + app/version_code.properties | 4 +- 71 files changed, 2169 insertions(+), 951 deletions(-) create mode 100644 app/EQC_G5.jks create mode 100644 app/src/main/java/com/ic/launcher/FragmentManage.java create mode 100644 app/src/main/java/com/ic/launcher/SelectDialActivity.java create mode 100644 app/src/main/java/com/ic/launcher/adapter/WatchPreviewAdapter.java create mode 100644 app/src/main/java/com/ic/launcher/entity/ClockDialEntity.java create mode 100644 app/src/main/java/com/ic/launcher/fragment/BaseFragment.java create mode 100644 app/src/main/java/com/ic/launcher/fragment/LowPowerModeFragment.java create mode 100644 app/src/main/java/com/ic/launcher/fragment/SelectClockDialFragment.java create mode 100644 app/src/main/java/com/ic/launcher/fragment/clock/Clock12DialFragment.java create mode 100644 app/src/main/java/com/ic/launcher/fragment/clock/Clock6DialFragment.java delete mode 100644 app/src/main/java/com/ic/launcher/fragment/l02/L02StatusBarFragment.java delete mode 100644 app/src/main/java/com/ic/launcher/fragment/l02/L02WatchFragment.java create mode 100644 app/src/main/java/com/ic/launcher/listener/ILowPowerCallPhoneListener.java create mode 100644 app/src/main/java/com/ic/launcher/listener/ILowPowerStateListener.java create mode 100644 app/src/main/java/com/ic/launcher/listener/ISelectDialListener.java create mode 100644 app/src/main/java/com/ic/launcher/mode/AnalogColorModel.java rename app/src/main/java/com/ic/launcher/mode/{AppListModel.java => AppModel.java} (51%) create mode 100644 app/src/main/java/com/ic/launcher/mode/BaseModel.java create mode 100644 app/src/main/java/com/ic/launcher/mode/LowPowerModel.java create mode 100644 app/src/main/java/com/ic/launcher/presenter/PresenterCycle.java create mode 100644 app/src/main/java/com/ic/launcher/widget/ClockDrawableView.java delete mode 100644 app/src/main/java/com/ic/launcher/widget/ClockWatchView.java create mode 100644 app/src/main/res/layout/activity_select_dial.xml create mode 100644 app/src/main/res/layout/fragment_clock_12_dial.xml create mode 100644 app/src/main/res/layout/fragment_clock_6_dial.xml delete mode 100644 app/src/main/res/layout/fragment_l02_status_bar.xml delete mode 100644 app/src/main/res/layout/fragment_l02_watch.xml create mode 100644 app/src/main/res/layout/fragment_low_power_mode.xml create mode 100644 app/src/main/res/layout/fragment_select_clock_dial.xml create mode 100644 app/src/main/res/layout/item_watch_preview.xml create mode 100644 app/src/main/res/mipmap-ldpi/clock12_dial_preview.png create mode 100644 app/src/main/res/mipmap-ldpi/clock6_dial_preview.png create mode 100644 app/src/main/res/mipmap-ldpi/clockl02_dial_preview.png create mode 100644 app/src/main/res/mipmap-mdpi/clock12_dial.png create mode 100644 app/src/main/res/mipmap-mdpi/clock12_hand_cap.png create mode 100644 app/src/main/res/mipmap-mdpi/clock12_hand_hour.png create mode 100644 app/src/main/res/mipmap-mdpi/clock12_hand_minute.png create mode 100644 app/src/main/res/mipmap-mdpi/clock12_hand_second.png create mode 100644 app/src/main/res/mipmap-mdpi/clock6_dial.png create mode 100644 app/src/main/res/mipmap-mdpi/clock6_hand_cap.png create mode 100644 app/src/main/res/mipmap-mdpi/clock6_hand_hour.png create mode 100644 app/src/main/res/mipmap-mdpi/clock6_hand_minute.png create mode 100644 app/src/main/res/mipmap-mdpi/clock6_hand_second.png create mode 100644 app/src/main/res/mipmap-mdpi/low_power_battery.png create mode 100644 app/src/main/res/mipmap-mdpi/low_power_dial.png create mode 100644 app/src/main/res/mipmap-mdpi/qs_background.png diff --git a/app/EQC_G5.jks b/app/EQC_G5.jks new file mode 100644 index 0000000000000000000000000000000000000000..2229d46ba5935ac0f52c19d953a9cdcb2069dcae GIT binary patch literal 4688 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 yc!wQL@>GyEE+vd+EajtTtTK9ZV#?b)@M+zHd + @@ -18,14 +19,23 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> - + - + + + + + + + + + + diff --git a/app/src/main/java/com/ic/launcher/FragmentManage.java b/app/src/main/java/com/ic/launcher/FragmentManage.java new file mode 100644 index 0000000..ed9a272 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/FragmentManage.java @@ -0,0 +1,203 @@ +package com.ic.launcher; + +import android.content.Context; +import android.util.SparseArray; + +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; + +import com.ic.launcher.fragment.AppListFragment; +import com.ic.launcher.fragment.L02MainFragment; +import com.ic.launcher.fragment.LowPowerModeFragment; +import com.ic.launcher.fragment.clock.Clock12DialFragment; +import com.ic.launcher.fragment.clock.Clock6DialFragment; +import com.ic.launcher.mode.L02MainModel; +import com.ic.launcher.util.SPUtils; + +import static com.ic.launcher.configure.l02.L02Icon.CLOCK_INDEX_12; +import static com.ic.launcher.configure.l02.L02Icon.CLOCK_INDEX_6; +import static com.ic.launcher.configure.l02.L02Icon.CLOCK_INDEX_L02; + +public class FragmentManage { + + private Context mContext; + + private final static int MAIN_FRAGMENT_INDEX = 0; + private final static int APP_FRAGMENT_INDEX = 1; + private final static int LOW_FRAGMENT_INDEX = 2; + + private SparseArray mAddFt; + + private FragmentManager ftManager; + + FragmentManage(Context context, FragmentManager ftManager) { + this.ftManager = ftManager; + mAddFt = new SparseArray<>(); + this.mContext = context; + } + + /** + * 去Sp中取值,没有 默认为 {@link L02MainFragment} 数字表盘 + * 可能的值为 {@link Clock6DialFragment} 或者 {@link Clock12DialFragment} 模拟表盘 + */ + + void showCurrMainFragment(boolean finish) { + Fragment fragment = getFragmentList(MAIN_FRAGMENT_INDEX); + if (fragment == null) { + fragment = getCurrMainFragment(); + addFragmentList(MAIN_FRAGMENT_INDEX, fragment); + } + addOrShowFragment(finish, fragment); + } + + void showAppFragment(boolean finish, int flag) { + Fragment fragment = getFragmentList(APP_FRAGMENT_INDEX); + if (fragment == null) { + fragment = AppListFragment.newInstance(flag); + addFragmentList(APP_FRAGMENT_INDEX, fragment); + } else { + ((AppListFragment) fragment).setMoveEndItem(flag != 1); + } + addOrShowFragment(finish, fragment); + } + + void changeMainClock(boolean finish) { + Fragment fragment = getCurrMainFragment(); + Fragment oldFt = getFragmentList(MAIN_FRAGMENT_INDEX); + if ((fragment instanceof L02MainFragment && oldFt instanceof L02MainFragment) + || (fragment instanceof Clock6DialFragment && oldFt instanceof Clock6DialFragment) + || (fragment instanceof Clock12DialFragment && oldFt instanceof Clock12DialFragment)) { + return; + } + + replaceMainFragment(finish, fragment); + } + + boolean onBackFragment(boolean finish) { + if (mAddFt.get(0).isVisible()) { + return true; + } + + if (mAddFt.get(1).isVisible()) { + showCurrMainFragment(finish); + return true; + } + + return false; + } + + void gotoLowPowerMode(boolean finish) { + + Fragment fragment = getFragmentList(LOW_FRAGMENT_INDEX); + + //如果不为空,表示已经处理低电量模式 + if (fragment != null) { + return; + } + + fragment = LowPowerModeFragment.newInstance(); + + + replaceLowFragment(finish, fragment); + } + + void quitLowPowerMode(boolean finish) { + + Fragment fragment = getFragmentList(LOW_FRAGMENT_INDEX); + //如果为空,表示已经不在低电量模式 + if (fragment == null) { + return; + } + + Fragment mainFt = getCurrMainFragment(); + + replaceMainFragment(finish, mainFt); + } + + + private Fragment getCurrMainFragment() { + int main = SPUtils.getClockDialSP(mContext); + switch (main) { + case CLOCK_INDEX_6: + return Clock6DialFragment.newInstance(); + case CLOCK_INDEX_12: + return Clock12DialFragment.newInstance(); + default: + return L02MainFragment.newInstance(); + } + } + + private Fragment getFragmentList(int index) { + return mAddFt.get(index); + } + + private void addFragmentList(int index, Fragment fragment) { + mAddFt.put(index, fragment); + } + + + private void replaceMainFragment(boolean finish, Fragment fragment) { + if (finish || fragment == null) { + return; + } + + FragmentTransaction ft = ftManager.beginTransaction(); + Fragment dd = mAddFt.get(MAIN_FRAGMENT_INDEX); + if(dd != null){ + ft.remove(mAddFt.get(MAIN_FRAGMENT_INDEX)); + mAddFt.remove(MAIN_FRAGMENT_INDEX); + } + + addFragmentList(MAIN_FRAGMENT_INDEX, fragment); + + ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); + + ft.add(R.id.main_content_fl, fragment); + ft.commit(); + } + + private void replaceLowFragment(boolean finish, Fragment fragment) { + if (finish || fragment == null) { + return; + } + + FragmentTransaction ft = ftManager.beginTransaction(); + + for (int i = 0; i < mAddFt.size(); i++) { + ft.remove(mAddFt.get(i)); + mAddFt.remove(i); + } + + ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); + + addFragmentList(LOW_FRAGMENT_INDEX, fragment); + + ft.add(R.id.main_content_fl, fragment); + ft.commit(); + } + + private void addOrShowFragment(boolean finish, Fragment fragment) { + if (finish || fragment == null) { + return; + } + + FragmentTransaction ft = ftManager.beginTransaction(); + + for (int i = 0; i < mAddFt.size(); i++) { + if (mAddFt.get(i).isAdded()) { + ft.hide(mAddFt.get(i)); + } + } + + ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); + + if (fragment.isAdded()) { + ft.show(fragment); + } else { + ft.add(R.id.main_content_fl, fragment); + } + + ft.commit(); + } +} diff --git a/app/src/main/java/com/ic/launcher/IcLauncherApplication.java b/app/src/main/java/com/ic/launcher/IcLauncherApplication.java index 6a3005c..169218f 100644 --- a/app/src/main/java/com/ic/launcher/IcLauncherApplication.java +++ b/app/src/main/java/com/ic/launcher/IcLauncherApplication.java @@ -4,16 +4,17 @@ import android.app.Application; import com.ic.launcher.util.CrashHandler; import com.ic.launcher.util.IcLog; +import com.jakewharton.threetenabp.AndroidThreeTen; public class IcLauncherApplication extends Application { @Override public void onCreate() { super.onCreate(); - - IcLog.setLogHead("IcLauncher"); - CrashHandler crashHandler = CrashHandler.getInstance(); crashHandler.init(getApplicationContext()); + + IcLog.setLogHead("IcLauncher"); + AndroidThreeTen.init(this); } } diff --git a/app/src/main/java/com/ic/launcher/MainActivity.java b/app/src/main/java/com/ic/launcher/MainActivity.java index 6d52e7f..7a8ab87 100644 --- a/app/src/main/java/com/ic/launcher/MainActivity.java +++ b/app/src/main/java/com/ic/launcher/MainActivity.java @@ -1,146 +1,140 @@ package com.ic.launcher; import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.os.Bundle; -import android.util.SparseArray; import android.view.KeyEvent; -import com.ic.launcher.fragment.AppListFragment; -import com.ic.launcher.fragment.L02MainFragment; import com.ic.launcher.listener.IChangeMainFragmentListener; +import com.ic.launcher.listener.ILowPowerStateListener; import com.ic.launcher.listener.MainClockGestureDetectorImpl; +import com.ic.launcher.util.IcLog; import com.ic.launcher.util.ServiceUtil; import com.ic.launcher.util.SystemUtils; + public class MainActivity extends AppCompatActivity implements MainClockGestureDetectorImpl.OnClockGestureFlingListener, - IChangeMainFragmentListener { - - private static final String SERVICE_PKG_NAME = "com.enqualcomm.support"; - - private FragmentManager fragmentManager; + IChangeMainFragmentListener, + ILowPowerStateListener { - private SparseArray mAddFt; + private static final String TAG = "MainActivity"; - private L02MainFragment l02MainFt; - private AppListFragment appListFt; + private static final String SERVICE_PKG_NAME = "com.enqualcomm.support"; + private boolean isLowPower = false; + private FragmentManage ftManage; + private boolean isChangeClock=false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - mAddFt = new SparseArray<>(); - fragmentManager = getSupportFragmentManager(); - - l02MainFt = L02MainFragment.newInstance(); + ftManage = new FragmentManage(this,getSupportFragmentManager()); + ftManage.showCurrMainFragment(isFinishing()); - commitFragment(l02MainFt); + registerChangeClockReceiver(); ServiceUtil.startServiceUtil(getApplicationContext(), - "com.ic.action.WORK_SERVICE", getPackageName()); + "com.ic.action.WORK_SERVICE", getPackageName()); } @Override - public void onDouble() { - try { - String cid = SystemUtils.GetCidFromSystem(); - if (cid.startsWith("TESTPROTOCOL")) { - try { - // 协议测试 - Intent intent = getPackageManager().getLaunchIntentForPackage(SERVICE_PKG_NAME); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(intent); - } catch (Exception ignored) { - } - } - } catch (Exception ignored) { + protected void onResume() { + super.onResume(); + if(isChangeClock){ + ftManage.changeMainClock(isFinishing()); + isChangeClock=false; } } @Override - public void onDirection(int flag) { - switch (flag) { - case 1: - //左滑 - if (appListFt == null) { - appListFt = AppListFragment.newInstance(1); - } else { - appListFt.setMoveEndItem(false); - } - commitFragment(appListFt); - break; - case 2: - //右滑 - if (appListFt == null) { - appListFt = AppListFragment.newInstance(2); - } else { - appListFt.setMoveEndItem(true); - } - commitFragment(appListFt); - break; - } + protected void onDestroy() { + super.onDestroy(); + unRegisterTimeDateReceiver(); } @Override - public void onChangeMain() { - //app列表已滑动到第一个或者第二个,需要切换到主main - commitFragment(l02MainFt); + public void onDouble() { + if (isLowPower) return; + startTestProtocol(); } - private void commitFragment(Fragment fragment) { - if (isFinishing()) { - return; - } - - FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - - for (int i = 0; i < mAddFt.size(); i++) { - fragmentTransaction.hide(mAddFt.get(i)); - } + @Override + public void onDirection(int flag) { + if (isLowPower) return; + ftManage.showAppFragment(isFinishing(), flag); + } - fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); - //fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out); + @Override + public void onChangeMain() { + ftManage.showCurrMainFragment(isFinishing()); + } - if (fragment.isAdded()) { - fragmentTransaction.show(fragment); + @Override + public void onLowChange(boolean state) { + if (state) { + ftManage.gotoLowPowerMode(isFinishing()); } else { - putFragmentToArray(fragment); - fragmentTransaction.add(R.id.main_content_fl, fragment); + ftManage.quitLowPowerMode(isFinishing()); } - - //fragmentTransaction.commitAllowingStateLoss(); - - fragmentTransaction.commit(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { // 禁用 KEYCODE_BACK 退出功能 - if (mAddFt.get(0).isVisible()) { + if (ftManage.onBackFragment(isFinishing())) { return true; } + } + return super.onKeyDown(keyCode, event); + } - if(mAddFt.get(1).isVisible()){ - commitFragment(l02MainFt); - return true; + + private void startTestProtocol() { + try { + String cid = SystemUtils.GetCidFromSystem(); + if (cid.startsWith("TESTPROTOCOL")) { + try { + // 协议测试 + Intent intent = getPackageManager().getLaunchIntentForPackage(SERVICE_PKG_NAME); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + } catch (Exception ignored) { + } } + } catch (Exception ignored) { } - return super.onKeyDown(keyCode, event); } - private void putFragmentToArray(Fragment fragment) { - int flag = 0; - if (fragment instanceof AppListFragment) { - flag = 1; + private void registerChangeClockReceiver() { + IntentFilter filter = new IntentFilter(); + filter.addAction("com.ic.action.CHANGE_CLOCK"); + registerReceiver(mIntentReceiver, filter); + } + + private void unRegisterTimeDateReceiver() { + try { + unregisterReceiver(mIntentReceiver); + } catch (IllegalArgumentException e) { + IcLog.e(TAG, "unRegisterTimeDateReceiver", e); } - mAddFt.put(flag, fragment); } + + private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if ("com.ic.action.CHANGE_CLOCK".equals(action)) { + isChangeClock =true; + } + } + }; + } diff --git a/app/src/main/java/com/ic/launcher/SelectDialActivity.java b/app/src/main/java/com/ic/launcher/SelectDialActivity.java new file mode 100644 index 0000000..bb99324 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/SelectDialActivity.java @@ -0,0 +1,33 @@ +package com.ic.launcher; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; + +import android.os.Bundle; + +import com.ic.launcher.fragment.SelectClockDialFragment; + +public class SelectDialActivity extends AppCompatActivity { + + private FragmentManager ftManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_select_dial); + ftManager = getSupportFragmentManager(); + addOrShowFragment(isFinishing(),SelectClockDialFragment.newInstance()); + } + + private void addOrShowFragment(boolean finish, Fragment fragment) { + if (finish || fragment == null) { + return; + } + + FragmentTransaction ft = ftManager.beginTransaction(); + ft.add(R.id.select_dial_content_fl, fragment); + ft.commit(); + } +} diff --git a/app/src/main/java/com/ic/launcher/adapter/WatchPreviewAdapter.java b/app/src/main/java/com/ic/launcher/adapter/WatchPreviewAdapter.java new file mode 100644 index 0000000..d119bae --- /dev/null +++ b/app/src/main/java/com/ic/launcher/adapter/WatchPreviewAdapter.java @@ -0,0 +1,62 @@ +package com.ic.launcher.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.RecyclerView; + +import com.ic.launcher.databinding.ItemWatchPreviewBinding; +import com.ic.launcher.entity.ClockDialEntity; +import com.ic.launcher.listener.ISelectDialListener; + +import static com.ic.launcher.configure.l02.L02Icon.l02ClockDial; + +public class WatchPreviewAdapter extends RecyclerView.Adapter { + + private Context context; + private ISelectDialListener listener; + + public WatchPreviewAdapter(Context context,ISelectDialListener listener){ + this.context=context; + this.listener =listener; + } + + @NonNull + @Override + public PreviewViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new PreviewViewHolder(ItemWatchPreviewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull PreviewViewHolder holder, int position) { + holder.bindItem(context,l02ClockDial[position],listener); + } + + @Override + public int getItemCount() { + return l02ClockDial.length; + } + + class PreviewViewHolder extends RecyclerView.ViewHolder { + + private ItemWatchPreviewBinding binding = null; + + public PreviewViewHolder(@NonNull ItemWatchPreviewBinding itemView) { + super(itemView.getRoot()); + binding = itemView; + } + + public void bindItem(Context context,ClockDialEntity entity,ISelectDialListener listener) { + if (binding != null) { + binding.setEntity(entity); + binding.setOnClick(listener); + binding.setPreviewDrawable(ContextCompat.getDrawable(context,entity.getDialPreview())); + binding.executePendingBindings(); + } + } + } + +} diff --git a/app/src/main/java/com/ic/launcher/configure/l02/L02AppInfo.java b/app/src/main/java/com/ic/launcher/configure/l02/L02AppInfo.java index c1133fa..5c61d11 100644 --- a/app/src/main/java/com/ic/launcher/configure/l02/L02AppInfo.java +++ b/app/src/main/java/com/ic/launcher/configure/l02/L02AppInfo.java @@ -4,6 +4,7 @@ import android.graphics.Color; import com.ic.launcher.R; import com.ic.launcher.entity.AppInfoEntity; +import com.ic.launcher.fragment.LowPowerModeFragment; import java.util.ArrayList; import java.util.List; @@ -12,6 +13,10 @@ public class L02AppInfo { private static final int BACK_COLOUR = Color.parseColor("#000000"); + /** + * 拨号的顺序不能变 在低电量模式下会查找这个列表,然后查找索引为1的拨号, + * 如果要修改 请到 {@link LowPowerModeFragment} 中一并修改 + **/ public static final List mL02DefaultAppList = new ArrayList() { { //联系人 diff --git a/app/src/main/java/com/ic/launcher/configure/l02/L02Icon.java b/app/src/main/java/com/ic/launcher/configure/l02/L02Icon.java index ba58d9e..404945b 100644 --- a/app/src/main/java/com/ic/launcher/configure/l02/L02Icon.java +++ b/app/src/main/java/com/ic/launcher/configure/l02/L02Icon.java @@ -1,6 +1,7 @@ package com.ic.launcher.configure.l02; import com.ic.launcher.R; +import com.ic.launcher.entity.ClockDialEntity; public class L02Icon { @@ -63,4 +64,14 @@ public class L02Icon { R.mipmap.clockl02_minutes_8, R.mipmap.clockl02_minutes_9 }; + + public static final int CLOCK_INDEX_6 = 1701; + public static final int CLOCK_INDEX_L02 = 1702; + public static final int CLOCK_INDEX_12 = 1703; + + public static ClockDialEntity[] l02ClockDial = new ClockDialEntity[]{ + new ClockDialEntity("clock16",CLOCK_INDEX_6,R.mipmap.clock6_dial_preview), + new ClockDialEntity("clockl02",CLOCK_INDEX_L02,R.mipmap.clockl02_dial_preview), + new ClockDialEntity("clock12",CLOCK_INDEX_12,R.mipmap.clock12_dial_preview), + }; } diff --git a/app/src/main/java/com/ic/launcher/entity/ClockDialEntity.java b/app/src/main/java/com/ic/launcher/entity/ClockDialEntity.java new file mode 100644 index 0000000..1b8eb2c --- /dev/null +++ b/app/src/main/java/com/ic/launcher/entity/ClockDialEntity.java @@ -0,0 +1,39 @@ +package com.ic.launcher.entity; + +import android.graphics.drawable.Drawable; + +public class ClockDialEntity { + private String dialKey; + private int dialValue; + private int dialPreview; + + public ClockDialEntity(String dialKey, int dialValue, int dialPreview) { + this.dialKey = dialKey; + this.dialValue = dialValue; + this.dialPreview = dialPreview; + } + + public String getDialKey() { + return dialKey; + } + + public void setDialKey(String dialKey) { + this.dialKey = dialKey; + } + + public int getDialValue() { + return dialValue; + } + + public void setDialValue(int dialValue) { + this.dialValue = dialValue; + } + + public int getDialPreview() { + return dialPreview; + } + + public void setDialPreview(int dialPreview) { + this.dialPreview = dialPreview; + } +} diff --git a/app/src/main/java/com/ic/launcher/fragment/AppListFragment.java b/app/src/main/java/com/ic/launcher/fragment/AppListFragment.java index 904b576..f5fa09c 100644 --- a/app/src/main/java/com/ic/launcher/fragment/AppListFragment.java +++ b/app/src/main/java/com/ic/launcher/fragment/AppListFragment.java @@ -2,10 +2,12 @@ package com.ic.launcher.fragment; import android.content.Context; +import android.graphics.Rect; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.PagerSnapHelper; @@ -14,6 +16,7 @@ import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import com.ic.launcher.IcLauncherApplication; import com.ic.launcher.R; @@ -21,7 +24,7 @@ import com.ic.launcher.adapter.AppInfoAdapter; import com.ic.launcher.adapter.IndicatorAdapter; import com.ic.launcher.listener.IChangeMainFragmentListener; import com.ic.launcher.listener.ICheckAppItemListener; -import com.ic.launcher.mode.AppListModel; +import com.ic.launcher.mode.AppModel; import com.ic.launcher.util.IcLog; @@ -29,14 +32,14 @@ public class AppListFragment extends Fragment { private static final String TAG = "AppListFragment"; private Context mContext; + private RecyclerView mAppRv; - private IcLauncherApplication mApp; + private AppModel appModel; private IChangeMainFragmentListener changeMainFragmentListener; private AppInfoAdapter appAdapter; - private AppListModel appListModel; private RecyclerView indicatorRv; private IndicatorAdapter indicatorAdapter; @@ -47,13 +50,9 @@ public class AppListFragment extends Fragment { @Override public void onAttach(@NonNull Context context) { super.onAttach(context); - this.mContext = context; - + mContext = context; if (context instanceof IChangeMainFragmentListener) { changeMainFragmentListener = (IChangeMainFragmentListener) context; - } else { - throw new RuntimeException(context.toString() - + " must implement MainClockGestureDetectorImpl.OnClockGestureFlingListener"); } } @@ -68,11 +67,13 @@ public class AppListFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mApp = (IcLauncherApplication) mContext.getApplicationContext(); Bundle bundle = getArguments(); if (bundle != null) { mCurrType = bundle.getInt("type"); } + + appModel = initFragmentModel(getActivity()); + onObserveModelValue(appModel); } @Override @@ -81,17 +82,14 @@ public class AppListFragment extends Fragment { View view = inflater.inflate(R.layout.fragment_app_list, container, false); mAppRv = view.findViewById(R.id.app_list); indicatorRv = view.findViewById(R.id.app_indicator_rv); - initRecyclerView(); - initAppListModel(); - + appModel.updateAppInfoList(); return view; } @Override public void onResume() { super.onResume(); - IcLog.i(TAG, "onResume"); if (mCurrType == 2) { //只有初始化进来的时候才执行, mAppRv.scrollToPosition(appAdapter.getAppEndIndex()); @@ -100,12 +98,6 @@ public class AppListFragment extends Fragment { } } - @Override - public void onPause() { - super.onPause(); - IcLog.i(TAG, "onPause"); - } - public void setMoveEndItem(boolean move) { if (move) { mAppRv.scrollToPosition(appAdapter.getAppEndIndex()); @@ -116,6 +108,18 @@ public class AppListFragment extends Fragment { } } + private AppModel initFragmentModel(FragmentActivity activity) { + AppModel.Factory factory = new AppModel.Factory((IcLauncherApplication) mContext.getApplicationContext()); + return new ViewModelProvider(activity, factory).get(AppModel.class); + } + + private void onObserveModelValue(AppModel baseModel) { + baseModel.getObservableAppList().observe(this, appList -> appAdapter.updateAppInfoList(appList)); + baseModel.getObservableAppState().observe(this, this::initIndicator); + baseModel.getObservableErrorInfo().observe(this, info -> Toast.makeText(mContext, info, Toast.LENGTH_SHORT).show()); + } + + private void initRecyclerView() { appAdapter = new AppInfoAdapter(mContext, itemListener); LinearLayoutManager mLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false); @@ -123,28 +127,17 @@ public class AppListFragment extends Fragment { mAppRv.setLayoutManager(mLayoutManager); mAppRv.setAdapter(appAdapter); + new PagerSnapHelper().attachToRecyclerView(mAppRv); mAppRv.addOnScrollListener(scrollListener); } - private void initAppListModel() { - AppListModel.Factory factory = new AppListModel.Factory(mApp); - appListModel = new ViewModelProvider(this, factory).get(AppListModel.class); - - appListModel.getObsAppInfoList().observe(getViewLifecycleOwner(), appList -> { - appAdapter.updateAppInfoList(appList); - }); - - appListModel.getObsAppState().observe(getViewLifecycleOwner(), this::initIndicator); - - appListModel.updateAppInfoList(); - } - private void initIndicator(boolean[] state) { indicatorAdapter = new IndicatorAdapter(state); LinearLayoutManager mLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false); indicatorRv.setLayoutManager(mLayoutManager); + indicatorRv.addItemDecoration(new SpacesItemDecoration(4)); indicatorRv.setAdapter(indicatorAdapter); } @@ -202,12 +195,20 @@ public class AppListFragment extends Fragment { } }; - private ICheckAppItemListener itemListener = new ICheckAppItemListener() { - @Override - public void onAppItem(int pos) { - appListModel.onStartAppActivity(pos); + public 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; + } + } + private ICheckAppItemListener itemListener = pos -> appModel.onStartAppActivity(pos); } diff --git a/app/src/main/java/com/ic/launcher/fragment/BaseFragment.java b/app/src/main/java/com/ic/launcher/fragment/BaseFragment.java new file mode 100644 index 0000000..6c540e5 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/fragment/BaseFragment.java @@ -0,0 +1,91 @@ +package com.ic.launcher.fragment; + +import android.annotation.SuppressLint; +import android.app.Application; +import android.content.Context; +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.view.GestureDetectorCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; + +import com.ic.launcher.IcLauncherApplication; +import com.ic.launcher.listener.MainClockGestureDetectorImpl; +import com.ic.launcher.mode.BaseModel; +import com.ic.launcher.util.IcLog; + +public abstract class BaseFragment extends Fragment { + + private static final String TAG = "BaseFragment"; + + protected Context mContext; + + protected BaseModel mBaseModel; + + private GestureDetectorCompat gesture; + private MainClockGestureDetectorImpl.OnClockGestureFlingListener flingListener; + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.mContext = context; + + if (context instanceof MainClockGestureDetectorImpl.OnClockGestureFlingListener) { + flingListener = (MainClockGestureDetectorImpl.OnClockGestureFlingListener) context; + } + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + IcLog.i(TAG,"onCreate"); + mBaseModel = initFragmentModel(getActivity(), (IcLauncherApplication) mContext.getApplicationContext()); + onObserveModelValue(mBaseModel); + mBaseModel.OnUiCreate(); + } + + @Override + public void onResume() { + super.onResume(); + IcLog.i(TAG,"onResume"); + if(mBaseModel != null){ + mBaseModel.OnUiResume(); + } + } + + @Override + public void onPause() { + super.onPause(); + IcLog.i(TAG,"onPause"); + if(mBaseModel != null){ + mBaseModel.OnUiPause(); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + IcLog.i(TAG,"onDestroy"); + if(mBaseModel != null){ + mBaseModel.OnUiDestroy(); + } + } + + protected abstract BaseModel initFragmentModel(FragmentActivity activity, Application application); + protected abstract void onObserveModelValue(BaseModel baseModel); + + + @SuppressLint("ClickableViewAccessibility") + protected void initOnTouchListener(View view) { + gesture = new GestureDetectorCompat(mContext, new MainClockGestureDetectorImpl(flingListener)); + view.setOnTouchListener((v, event) -> { + if (gesture.onTouchEvent(event)) { + return true; + } + return true; + }); + } +} diff --git a/app/src/main/java/com/ic/launcher/fragment/L02MainFragment.java b/app/src/main/java/com/ic/launcher/fragment/L02MainFragment.java index 503d562..acd042a 100644 --- a/app/src/main/java/com/ic/launcher/fragment/L02MainFragment.java +++ b/app/src/main/java/com/ic/launcher/fragment/L02MainFragment.java @@ -1,43 +1,32 @@ package com.ic.launcher.fragment; -import android.annotation.SuppressLint; +import android.app.Application; import android.content.Context; import android.os.Bundle; import androidx.annotation.NonNull; -import androidx.core.view.GestureDetectorCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentTransaction; +import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.ViewModelProvider; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import com.ic.launcher.IcLauncherApplication; -import com.ic.launcher.R; -import com.ic.launcher.fragment.l02.L02WatchFragment; -import com.ic.launcher.fragment.l02.L02StatusBarFragment; -import com.ic.launcher.listener.MainClockGestureDetectorImpl; +import com.ic.launcher.databinding.FragmentL02MainBinding; +import com.ic.launcher.listener.ILowPowerStateListener; +import com.ic.launcher.mode.BaseModel; import com.ic.launcher.mode.L02MainModel; import com.ic.launcher.util.IcLog; +import com.ic.launcher.util.SPUtils; -public class L02MainFragment extends Fragment { +public class L02MainFragment extends BaseFragment { private static final String TAG = "L02MainFragment"; - private Context mContext; - private IcLauncherApplication mApp; + private FragmentL02MainBinding mainBinding; - private L02MainModel watchMainModel; - - private L02StatusBarFragment statusBarFt; - private L02WatchFragment watchFt; - - private GestureDetectorCompat gesture; - - private MainClockGestureDetectorImpl.OnClockGestureFlingListener flingListener; + private ILowPowerStateListener lowPower; public static L02MainFragment newInstance() { return new L02MainFragment(); @@ -46,126 +35,126 @@ public class L02MainFragment extends Fragment { @Override public void onAttach(@NonNull Context context) { super.onAttach(context); - this.mContext = context; - if (context instanceof MainClockGestureDetectorImpl.OnClockGestureFlingListener) { - flingListener = (MainClockGestureDetectorImpl.OnClockGestureFlingListener) context; - } else { - throw new RuntimeException(context.toString() - + " must implement MainClockGestureDetectorImpl.OnClockGestureFlingListener"); + if (context instanceof ILowPowerStateListener) { + lowPower = (ILowPowerStateListener) context; } } @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mApp = (IcLauncherApplication) mContext.getApplicationContext(); + protected BaseModel initFragmentModel(FragmentActivity activity, Application application) { + L02MainModel.Factory factory = new L02MainModel.Factory(application); + return new ViewModelProvider(activity, factory).get(L02MainModel.class); + } + @Override + protected void onObserveModelValue(BaseModel baseModel) { + L02MainModel mainModel = (L02MainModel)baseModel; + observePhoneValue( mainModel); + observeBatteryValue(mainModel); + observeDataTimeValue(mainModel); + observeHardwareValue(mainModel); + + //进入电量模式 + baseModel.getObservableLowPower().observe(this,status ->{ + IcLog.i(TAG,"getObservableLowPower status"+status); + if(status){ + lowPower.onLowChange(true); + } + }); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_l02_main, container, false); - statusBarFt = (L02StatusBarFragment) getChildFragmentManager().findFragmentById(R.id.l02_status_fl); - watchFt = (L02WatchFragment) getChildFragmentManager().findFragmentById(R.id.l02_watch_fl); + mainBinding = FragmentL02MainBinding.inflate(inflater, container, false); + mainBinding.setHeartValue(String.valueOf(SPUtils.getBloodHeartSP(mContext))); + mainBinding.setStepValue("0"); //监听事件 - initL02MainModel(); - initOnTouchListener(view); - IcLog.i(TAG, "onCreateView"); - return view; - } - - @Override - public void onHiddenChanged(boolean hidden) { - super.onHiddenChanged(hidden); - if(hidden){ - IcLog.i(TAG, "Fragment hidden"); - }else{ - IcLog.i(TAG, "Fragment show"); - } - } - - @Override - public void onResume() { - super.onResume(); - if(watchMainModel != null){ - watchMainModel.onFragmentResume(); - } - IcLog.i(TAG, "onResume"); + initOnTouchListener(mainBinding.getRoot()); + return mainBinding.getRoot(); } - @Override - public void onPause() { - super.onPause(); - if(watchMainModel != null){ - watchMainModel.onFragmentPause(); - } - - IcLog.i(TAG, "onPause"); - } + private void observePhoneValue(L02MainModel model) { + model.getObservablePhoneType().observe(this, resID ->{ + if(mainBinding != null){ + mainBinding.setPhoneNetType(resID); + } - @Override - public void onDestroyView() { - super.onDestroyView(); - IcLog.i(TAG, "onDestroyView"); - if(watchMainModel != null){ - watchMainModel.onFragmentDestroy(); - } - } + }); - private void initL02MainModel() { - L02MainModel.Factory factory = new L02MainModel.Factory(mApp); + model.getObservableSignal().observe(this, resID ->{ + if(mainBinding != null){ + mainBinding.setPhoneSignal(resID); + } + }); - watchMainModel = new ViewModelProvider(this, factory).get(L02MainModel.class); - observeStateBarValue(watchMainModel); - observeWatchValue(watchMainModel); + model.getObservableTransport().observe(this, resID -> { + if(mainBinding != null){ + mainBinding.setPhoneTransport(resID); + } + }); } - private void observeStateBarValue(L02MainModel model) { - model.getObsPhoneSignalID().observe(getViewLifecycleOwner(), resID -> statusBarFt.updatePhoneSignal(resID)); - - model.getObsPhoneTransportID().observe(getViewLifecycleOwner(), resID -> statusBarFt.updateTransportValue(resID)); - - model.getObsPhoneTypeID().observe(getViewLifecycleOwner(), resID -> statusBarFt.updateNetTypeValue(resID)); + private void observeBatteryValue(L02MainModel model) { + model.getObservableBatteryValue().observe(this, value ->{ + if(mainBinding != null){ + mainBinding.setBatteryValue(value); + } - model.getObsBatteryCharging().observe(getViewLifecycleOwner(), charging -> statusBarFt.updateBatteryChargeValue(charging)); + }); - model.getObsBatteryResID().observe(getViewLifecycleOwner(), resID -> statusBarFt.updateBatteryDrawable(resID)); + model.getObservableBattery().observe(this, resID ->{ + if(mainBinding != null){ + mainBinding.setBatteryDrawable(resID); + } + }); - model.getObsBatteryValue().observe(getViewLifecycleOwner(), value -> statusBarFt.updateBatteryValue(value)); + model.getObservableBatteryCharging().observe(this, state -> { + if(mainBinding != null){ + mainBinding.setBatteryCharge(state); + } + }); } - private void observeWatchValue(L02MainModel model) { - model.getObsTime().observe(getViewLifecycleOwner(), timeList -> watchFt.updateTimeValue(timeList)); - - model.getObsWeek().observe(getViewLifecycleOwner(), week -> watchFt.updateWeekValue(week)); - - model.getObsYear().observe(getViewLifecycleOwner(), year -> watchFt.updateDateValue(year)); + private void observeDataTimeValue(L02MainModel model) { + model.getObservableWeek().observe(this, week ->{ + if(mainBinding != null){ + mainBinding.setWatchWeek(week); + } + }); - model.getObsHardwareHeart().observe(getViewLifecycleOwner(), heart -> watchFt.updateHeartValue(heart)); + model.getObservableYear().observe(this, year -> { + if(mainBinding != null){ + mainBinding.setWatchDate(year); + } + }); - model.getObsHardwarePed().observe(getViewLifecycleOwner(), ped -> watchFt.updatePedValue(ped)); + model.getObservableTime().observe(this, time -> { + if(mainBinding != null){ + updateTimeValue(time); + } + }); } + private void observeHardwareValue(L02MainModel model) { + model.getObservableHardwareHeart().observe(this, heart ->{ + if(mainBinding != null){ + mainBinding.setHeartValue(heart); + } + }); - private void controlStatusBar(boolean isShow) { - FragmentTransaction ft = getChildFragmentManager().beginTransaction(); - if (isShow && !statusBarFt.isVisible()) { - ft.show(statusBarFt).commit(); - } else { - ft.hide(statusBarFt).commit(); - } - } - - @SuppressLint("ClickableViewAccessibility") - private void initOnTouchListener(View view) { - gesture = new GestureDetectorCompat(mContext, new MainClockGestureDetectorImpl(flingListener)); - view.setOnTouchListener((v, event) -> { - if (gesture.onTouchEvent(event)) { - return true; + model.getObservableHardwarePed().observe(this, ped -> { + if(mainBinding != null){ + mainBinding.setStepValue(ped); } - return true; }); } + + private void updateTimeValue(int[] value){ + mainBinding.setHourTen(value[0]); + mainBinding.setHourBit(value[1]); + mainBinding.setMinuteTen(value[2]); + mainBinding.setMinuteBit(value[3]); + } } diff --git a/app/src/main/java/com/ic/launcher/fragment/LowPowerModeFragment.java b/app/src/main/java/com/ic/launcher/fragment/LowPowerModeFragment.java new file mode 100644 index 0000000..68eac0c --- /dev/null +++ b/app/src/main/java/com/ic/launcher/fragment/LowPowerModeFragment.java @@ -0,0 +1,121 @@ +package com.ic.launcher.fragment; + + +import android.app.Application; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.ViewModelProvider; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.ic.launcher.IcLauncherApplication; +import com.ic.launcher.configure.l02.L02AppInfo; +import com.ic.launcher.databinding.FragmentLowPowerModeBinding; +import com.ic.launcher.entity.AppInfoEntity; +import com.ic.launcher.listener.ILowPowerCallPhoneListener; +import com.ic.launcher.listener.ILowPowerStateListener; +import com.ic.launcher.mode.LowPowerModel; +import com.ic.launcher.util.IcLog; + +/** + * A simple {@link Fragment} subclass. + */ +public class LowPowerModeFragment extends Fragment { + + private static final String TAG = "LowPowerModeFragment"; + + private Context mContext; + + private LowPowerModel lowPowerModel; + + private FragmentLowPowerModeBinding mPowerModeBinding; + private String batteryValue; + + private ILowPowerStateListener lowPower; + + public static LowPowerModeFragment newInstance() { + return new LowPowerModeFragment(); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + + mContext = context; + if (context instanceof ILowPowerStateListener) { + lowPower = (ILowPowerStateListener) context; + } + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + IcLauncherApplication mApp = (IcLauncherApplication) mContext.getApplicationContext(); + lowPowerModel = initFragmentModel(getActivity(),mApp); + onObserveModelValue(lowPowerModel); + lowPowerModel.OnUiCreate(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + lowPowerModel.OnUiDestroy(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + mPowerModeBinding = FragmentLowPowerModeBinding.inflate(inflater, container, false); + mPowerModeBinding.setCallPhone(callListener); + mPowerModeBinding.setLowPowerValue(batteryValue); + return mPowerModeBinding.getRoot(); + } + + private LowPowerModel initFragmentModel(FragmentActivity activity, Application application){ + LowPowerModel.Factory factory = new LowPowerModel.Factory(application); + return new ViewModelProvider(activity, factory).get(LowPowerModel.class); + } + + private void onObserveModelValue(LowPowerModel baseModel) { + baseModel.getObservableLowPowerValue().observe(this, this::updateLowPowerValue); + + //退出低电量模式 + baseModel.getObservableLowPower().observe(this,status ->{ + IcLog.i(TAG,"getObservableLowPower status"+status); + if(!status){ + lowPower.onLowChange(false); + } + }); + } + + private void updateLowPowerValue(String value){ + if(mPowerModeBinding != null){ + mPowerModeBinding.setLowPowerValue(value); + } + batteryValue= value; + } + + private ILowPowerCallPhoneListener callListener = () -> { + AppInfoEntity entity = L02AppInfo.mL02DefaultAppList.get(1); + if(entity != null){ + try { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setComponent(new ComponentName(entity.getPackageName(), entity.getActivityName())); + mContext.startActivity(intent); + }catch (Exception e){ + IcLog.e(TAG,"ILowPowerCallPhoneListener",e); + } + } + }; +} diff --git a/app/src/main/java/com/ic/launcher/fragment/SelectClockDialFragment.java b/app/src/main/java/com/ic/launcher/fragment/SelectClockDialFragment.java new file mode 100644 index 0000000..ac94030 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/fragment/SelectClockDialFragment.java @@ -0,0 +1,99 @@ +package com.ic.launcher.fragment; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Rect; +import android.net.Uri; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager2.widget.ViewPager2; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.ic.launcher.R; +import com.ic.launcher.adapter.WatchPreviewAdapter; +import com.ic.launcher.listener.ISelectDialListener; +import com.ic.launcher.util.SPUtils; + +import static java.lang.Math.abs; + + +public class SelectClockDialFragment extends Fragment { + + private Context mContext; + private int pageTranslationX; + + public static SelectClockDialFragment newInstance() { + return new SelectClockDialFragment(); + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + this.mContext =context; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_select_clock_dial, container, false); + + + final ViewPager2 viewPager2 = view.findViewById(R.id.select_clock_page); + WatchPreviewAdapter viewPagerAdapter = new WatchPreviewAdapter(mContext,listener); + viewPager2.setAdapter(viewPagerAdapter); + + viewPager2.setOffscreenPageLimit(1); + int nextItemVisiblePx = (int)getResources().getDimension(R.dimen.viewpager_next_item_visible); + int currentItemHorizontalMarginPx = (int)getResources().getDimension(R.dimen.viewpager_current_item_horizontal_margin); + pageTranslationX= nextItemVisiblePx + currentItemHorizontalMarginPx; + + viewPager2.setPageTransformer(new CustomPageTransformer()); + + viewPager2.addItemDecoration(new SpacesItemDecoration(currentItemHorizontalMarginPx)); + + return view; + } + + public 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; + } + } + + public class CustomPageTransformer implements ViewPager2.PageTransformer { + @Override + public void transformPage(@NonNull View page, float position) { + page.setTranslationX(-pageTranslationX*position); + page.setScaleY(1 - (0.35f * abs(position))); + } + } + + private ISelectDialListener listener = entity -> { + SPUtils.setClockDialSP(mContext,entity.getDialValue()); + sendChangeMainClock(); + if(getActivity() != null){ + getActivity().finish(); + } + }; + + private void sendChangeMainClock(){ + Intent intent = new Intent(); + intent.setAction("com.ic.action.CHANGE_CLOCK"); + mContext.sendBroadcast(intent); + } +} diff --git a/app/src/main/java/com/ic/launcher/fragment/clock/Clock12DialFragment.java b/app/src/main/java/com/ic/launcher/fragment/clock/Clock12DialFragment.java new file mode 100644 index 0000000..4e49fb0 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/fragment/clock/Clock12DialFragment.java @@ -0,0 +1,53 @@ +package com.ic.launcher.fragment.clock; + +import android.app.Application; +import android.os.Bundle; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + + +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.ViewModelProvider; + +import com.ic.launcher.IcLauncherApplication; +import com.ic.launcher.R; +import com.ic.launcher.fragment.BaseFragment; +import com.ic.launcher.mode.AnalogColorModel; +import com.ic.launcher.mode.BaseModel; +import com.ic.launcher.widget.ClockDrawableView; + + +public class Clock12DialFragment extends BaseFragment { + + private ClockDrawableView clockDrawableView; + + public static Clock12DialFragment newInstance() { + return new Clock12DialFragment(); + } + + @Override + protected BaseModel initFragmentModel(FragmentActivity activity, Application application) { + AnalogColorModel.Factory factory = new AnalogColorModel.Factory(application); + return new ViewModelProvider(activity, factory).get(AnalogColorModel.class); + } + + @Override + protected void onObserveModelValue(BaseModel baseModel) { + AnalogColorModel analogModel = (AnalogColorModel) baseModel; + analogModel.getObservableHourList().observe(this,hours ->{ + clockDrawableView.onTimeChanged(hours[0],hours[1],hours[2]); + }); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_clock_12_dial, container, false); + clockDrawableView = view.findViewById(R.id.clock_12_drawable_view); + initOnTouchListener(view); + return view; + } + +} diff --git a/app/src/main/java/com/ic/launcher/fragment/clock/Clock6DialFragment.java b/app/src/main/java/com/ic/launcher/fragment/clock/Clock6DialFragment.java new file mode 100644 index 0000000..54e0af4 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/fragment/clock/Clock6DialFragment.java @@ -0,0 +1,50 @@ +package com.ic.launcher.fragment.clock; +import android.app.Application; +import android.os.Bundle; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.ViewModelProvider; + +import com.ic.launcher.R; +import com.ic.launcher.fragment.BaseFragment; +import com.ic.launcher.mode.AnalogColorModel; +import com.ic.launcher.mode.BaseModel; +import com.ic.launcher.widget.ClockDrawableView; + + +public class Clock6DialFragment extends BaseFragment { + + private ClockDrawableView clockDrawableView; + + public static Clock6DialFragment newInstance() { + return new Clock6DialFragment(); + } + + @Override + protected BaseModel initFragmentModel(FragmentActivity activity, Application application) { + AnalogColorModel.Factory factory = new AnalogColorModel.Factory(application); + return new ViewModelProvider(activity, factory).get(AnalogColorModel.class); + } + + @Override + protected void onObserveModelValue(BaseModel baseModel) { + AnalogColorModel analogModel = (AnalogColorModel) baseModel; + analogModel.getObservableHourList().observe(this,hours ->{ + clockDrawableView.onTimeChanged(hours[0],hours[1],hours[2]); + }); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_clock_6_dial, container, false); + clockDrawableView = view.findViewById(R.id.clock_6_drawable_view); + initOnTouchListener(view); + return view; + } + +} diff --git a/app/src/main/java/com/ic/launcher/fragment/l02/L02StatusBarFragment.java b/app/src/main/java/com/ic/launcher/fragment/l02/L02StatusBarFragment.java deleted file mode 100644 index 63bc6da..0000000 --- a/app/src/main/java/com/ic/launcher/fragment/l02/L02StatusBarFragment.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.ic.launcher.fragment.l02; - - -import android.content.Context; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.ic.launcher.databinding.FragmentL02StatusBarBinding; -import com.ic.launcher.util.IcLog; - - -public class L02StatusBarFragment extends Fragment { - private static final String TAG = "L02StatusBarFt"; - private FragmentL02StatusBarBinding mStateBarBinding; - - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - mStateBarBinding = FragmentL02StatusBarBinding.inflate(inflater, container, false); - return mStateBarBinding.getRoot(); - } - - public void updateBatteryValue(String value) { - mStateBarBinding.setBatteryValue(value); - } - - public void updateBatteryDrawable(int drawableRes) { - mStateBarBinding.setBatteryDrawable(drawableRes); - } - - public void updateBatteryChargeValue(boolean state) { - mStateBarBinding.setBatteryCharge(state); - } - - public void updatePhoneSignal(int value) { - mStateBarBinding.setPhoneSignal(value); - } - - public void updateTransportValue(int value) { - mStateBarBinding.setPhoneTransport(value); - } - - public void updateNetTypeValue(int value) { - mStateBarBinding.setPhoneNetType(value); - } -} diff --git a/app/src/main/java/com/ic/launcher/fragment/l02/L02WatchFragment.java b/app/src/main/java/com/ic/launcher/fragment/l02/L02WatchFragment.java deleted file mode 100644 index d2099d1..0000000 --- a/app/src/main/java/com/ic/launcher/fragment/l02/L02WatchFragment.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.ic.launcher.fragment.l02; - - -import android.content.Context; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.ic.launcher.databinding.FragmentL02WatchBinding; -import com.ic.launcher.util.SPUtils; - -import java.util.ArrayList; -import java.util.List; - -public class L02WatchFragment extends Fragment { - - private static final String TAG = "L02WatchFragment"; - - private Context mContext; - private FragmentL02WatchBinding watchBinding; - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - mContext = context; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - public View onCreateView(LayoutInflater inflater, - ViewGroup container, - Bundle savedInstanceState) { - - watchBinding = FragmentL02WatchBinding.inflate(inflater, container, false); - updateHeartValue(String.valueOf(SPUtils.getBloodHeartSP(mContext))); - updatePedValue("0"); - return watchBinding.getRoot(); - } - - @Override - public void onResume() { - super.onResume(); - } - - @Override - public void onPause() { - super.onPause(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - } - - public void updateHeartValue(String value){ - watchBinding.setHeartValue(value); - } - - public void updatePedValue(String value){ - watchBinding.setStepValue(value); - } - - public void updateWeekValue(String value){ - watchBinding.setWatchWeek(value); - } - - public void updateDateValue(String value){ - watchBinding.setWatchDate(value); - } - - public void updateTimeValue(ArrayList value){ - watchBinding.setTimeText(value); - } -} diff --git a/app/src/main/java/com/ic/launcher/listener/ILowPowerCallPhoneListener.java b/app/src/main/java/com/ic/launcher/listener/ILowPowerCallPhoneListener.java new file mode 100644 index 0000000..a580a96 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/listener/ILowPowerCallPhoneListener.java @@ -0,0 +1,5 @@ +package com.ic.launcher.listener; + +public interface ILowPowerCallPhoneListener { + void onCallPhone(); +} diff --git a/app/src/main/java/com/ic/launcher/listener/ILowPowerStateListener.java b/app/src/main/java/com/ic/launcher/listener/ILowPowerStateListener.java new file mode 100644 index 0000000..2e9f7ad --- /dev/null +++ b/app/src/main/java/com/ic/launcher/listener/ILowPowerStateListener.java @@ -0,0 +1,5 @@ +package com.ic.launcher.listener; + +public interface ILowPowerStateListener { + void onLowChange(boolean state); +} diff --git a/app/src/main/java/com/ic/launcher/listener/ISelectDialListener.java b/app/src/main/java/com/ic/launcher/listener/ISelectDialListener.java new file mode 100644 index 0000000..ac5816b --- /dev/null +++ b/app/src/main/java/com/ic/launcher/listener/ISelectDialListener.java @@ -0,0 +1,7 @@ +package com.ic.launcher.listener; + +import com.ic.launcher.entity.ClockDialEntity; + +public interface ISelectDialListener { + void onSelectDial(ClockDialEntity entity); +} diff --git a/app/src/main/java/com/ic/launcher/mode/AnalogColorModel.java b/app/src/main/java/com/ic/launcher/mode/AnalogColorModel.java new file mode 100644 index 0000000..d914cac --- /dev/null +++ b/app/src/main/java/com/ic/launcher/mode/AnalogColorModel.java @@ -0,0 +1,48 @@ +package com.ic.launcher.mode; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import com.ic.launcher.presenter.PresenterCycle; +import com.ic.launcher.presenter.TimeDatePresenter; + +public class AnalogColorModel extends BaseModel{ + + AnalogColorModel(@NonNull Application application) { + super(application); + PresenterCycle state = getPresenterList(TIME_LIST_INDEX); + if(state != null){ + ((TimeDatePresenter)state).setAnalogClock(true); + } + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + + @NonNull + private final Application mApplication; + + + public Factory(@NonNull Application application) { + mApplication = application; + } + + @SuppressWarnings("unchecked") + @Override + @NonNull + public T create(@NonNull Class modelClass) { + return (T) new AnalogColorModel(mApplication); + } + } + + public LiveData getObservableHourList() { + PresenterCycle state = getPresenterList(TIME_LIST_INDEX); + if(state != null){ + return ((TimeDatePresenter)state).getObsHourList(); + } + return null; + } +} diff --git a/app/src/main/java/com/ic/launcher/mode/AppListModel.java b/app/src/main/java/com/ic/launcher/mode/AppModel.java similarity index 51% rename from app/src/main/java/com/ic/launcher/mode/AppListModel.java rename to app/src/main/java/com/ic/launcher/mode/AppModel.java index f5e4d14..c7230f5 100644 --- a/app/src/main/java/com/ic/launcher/mode/AppListModel.java +++ b/app/src/main/java/com/ic/launcher/mode/AppModel.java @@ -13,42 +13,50 @@ import com.ic.launcher.presenter.AppListPresenter; import java.util.List; - -public class AppListModel extends AndroidViewModel { +public class AppModel extends AndroidViewModel { private final AppListPresenter appListPresenter; - private final LiveData> mObsAppInfoList; - private final LiveData mObsAppState; - private final LiveData mObsActivityError; - - public AppListModel(@NonNull Application application) { + private AppModel(Application application) { super(application); - this.appListPresenter = new AppListPresenter(application); - mObsAppInfoList = appListPresenter.getObsAppInfoList(); + appListPresenter = new AppListPresenter(application); - mObsAppState = appListPresenter.getObsAppState(); - mObsActivityError = appListPresenter.getObsActivityError(); } - public LiveData> getObsAppInfoList() { - return mObsAppInfoList; + public void updateAppInfoList() { + if (appListPresenter != null) { + appListPresenter.updateSystemApp(); + } + } - public LiveData getObsAppState() { - return mObsAppState; + public void onStartAppActivity(int pos) { + if (appListPresenter != null) { + appListPresenter.startAppActivity(pos); + } + } - public LiveData getObsActivityError() { - return mObsActivityError; + public LiveData> getObservableAppList() { + if (appListPresenter != null) { + return appListPresenter.getObsAppInfoList(); + } + + return null; } - public void updateAppInfoList() { - appListPresenter.updateSystemApp(); + public LiveData getObservableAppState() { + if (appListPresenter != null) { + return appListPresenter.getObsAppState(); + } + return null; } - public void onStartAppActivity(int pos) { - appListPresenter.startAppActivity(pos); + public LiveData getObservableErrorInfo() { + if (appListPresenter != null) { + return appListPresenter.getObsActivityError(); + } + return null; } public static class Factory extends ViewModelProvider.NewInstanceFactory { @@ -56,6 +64,7 @@ public class AppListModel extends AndroidViewModel { @NonNull private final Application mApplication; + public Factory(@NonNull Application application) { mApplication = application; } @@ -64,7 +73,7 @@ public class AppListModel extends AndroidViewModel { @Override @NonNull public T create(@NonNull Class modelClass) { - return (T) new AppListModel(mApplication); + return (T) new AppModel(mApplication); } } } diff --git a/app/src/main/java/com/ic/launcher/mode/BaseModel.java b/app/src/main/java/com/ic/launcher/mode/BaseModel.java new file mode 100644 index 0000000..8a56e99 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/mode/BaseModel.java @@ -0,0 +1,73 @@ +package com.ic.launcher.mode; + +import android.app.Application; +import android.util.SparseArray; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; + +import com.ic.launcher.presenter.BatteryPresenter; +import com.ic.launcher.presenter.PresenterCycle; +import com.ic.launcher.presenter.TimeDatePresenter; + +public abstract class BaseModel extends AndroidViewModel { + + protected final static int PHONE_LIST_INDEX = 0; + protected final static int BATTERY_LIST_INDEX = 1; + protected final static int TIME_LIST_INDEX = 2; + protected final static int HARDWARE_LIST_INDEX = 3; + + private final SparseArray mPresenter; + + BaseModel(@NonNull Application application) { + super(application); + mPresenter = new SparseArray<>(); + + BatteryPresenter batteryPresenter = new BatteryPresenter(application.getApplicationContext()); + TimeDatePresenter timeDatePresenter = new TimeDatePresenter(application.getApplicationContext()); + + addPresenterList(BATTERY_LIST_INDEX, batteryPresenter); + addPresenterList(TIME_LIST_INDEX, timeDatePresenter); + } + + PresenterCycle getPresenterList(int index) { + return mPresenter.get(index); + } + + void addPresenterList(int index, PresenterCycle cycle) { + mPresenter.put(index, cycle); + } + + public void OnUiCreate() { + for (int i = 0; i < mPresenter.size(); i++) { + mPresenter.valueAt(i).onPresenterCreate(); + } + } + + public void OnUiResume() { + for (int i = 0; i < mPresenter.size(); i++) { + mPresenter.valueAt(i).onPresenterResume(); + } + } + + public void OnUiPause() { + for (int i = 0; i < mPresenter.size(); i++) { + mPresenter.valueAt(i).onPresenterPause(); + } + } + + public void OnUiDestroy() { + for (int i = 0; i < mPresenter.size(); i++) { + mPresenter.valueAt(i).onPresenterDestroy(); + } + } + + public LiveData getObservableLowPower() { + PresenterCycle state = getPresenterList(BATTERY_LIST_INDEX); + if(state != null){ + return ((BatteryPresenter)state).getObsLowPower(); + } + return null; + } +} diff --git a/app/src/main/java/com/ic/launcher/mode/L02MainModel.java b/app/src/main/java/com/ic/launcher/mode/L02MainModel.java index c5534ab..dfb623b 100644 --- a/app/src/main/java/com/ic/launcher/mode/L02MainModel.java +++ b/app/src/main/java/com/ic/launcher/mode/L02MainModel.java @@ -3,7 +3,6 @@ package com.ic.launcher.mode; import android.app.Application; import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; @@ -11,82 +10,28 @@ import androidx.lifecycle.ViewModelProvider; import com.ic.launcher.presenter.BatteryPresenter; import com.ic.launcher.presenter.HardwarePresenter; import com.ic.launcher.presenter.PhoneStatePresenter; +import com.ic.launcher.presenter.PresenterCycle; import com.ic.launcher.presenter.TimeDatePresenter; -import com.ic.launcher.util.IcLog; -import java.util.ArrayList; -public class L02MainModel extends AndroidViewModel { +public class L02MainModel extends BaseModel { private static final String TAG = "L02MainModel"; - private final PhoneStatePresenter phonePresenter; - private final BatteryPresenter batteryPresenter; - private final TimeDatePresenter timeDatePresenter; - private final HardwarePresenter hardwarePresenter; - - private final LiveData mObsPhoneTypeID; - private final LiveData mObsPhoneSignalID; - private final LiveData mObsPhoneTransportID; - - private final LiveData mObsBatteryValue; - private final LiveData mObsBatteryCharging; - private final LiveData mObsBatteryResID; - - private final LiveData> mObsTime; - private final LiveData mObsYear; - private final LiveData mObsWeek; - - private final LiveData mObsHardwareHeart; - private final LiveData mObsHardwarePed; - - public L02MainModel(@NonNull Application application) { + private L02MainModel(Application application) { super(application); - this.phonePresenter = new PhoneStatePresenter(application.getApplicationContext()); - this.batteryPresenter = new BatteryPresenter(application.getApplicationContext()); - this.timeDatePresenter = new TimeDatePresenter(application.getApplicationContext()); - this.hardwarePresenter = new HardwarePresenter(application.getApplicationContext()); - - mObsPhoneSignalID = phonePresenter.getPhoneSignalObservable(); - mObsPhoneTypeID = phonePresenter.getPhoneTypeObservable(); - mObsPhoneTransportID = phonePresenter.getPhoneTransportObservable(); - - mObsBatteryCharging = batteryPresenter.getObsBatteryCharging(); - mObsBatteryResID = batteryPresenter.getObsBatteryResID(); - mObsBatteryValue = batteryPresenter.getObsBatteryValue(); + PhoneStatePresenter phonePresenter = new PhoneStatePresenter(application.getApplicationContext()); + HardwarePresenter hardwarePresenter = new HardwarePresenter(application.getApplicationContext()); - mObsTime = timeDatePresenter.getObsTime(); - mObsYear = timeDatePresenter.getObsYear(); - mObsWeek = timeDatePresenter.getmObsWeek(); - - mObsHardwareHeart = hardwarePresenter.getObsHardwareHeart(); - mObsHardwarePed = hardwarePresenter.getObsHardwarePed(); - } - - public void onFragmentCreate(){ - IcLog.i(TAG,"onFragmentCreate"); - } - - public void onFragmentResume(){ - IcLog.i(TAG,"onFragmentResume"); - hardwarePresenter.sendGetPedBroadcast(); - timeDatePresenter.onResumePresenter(); - phonePresenter.onResumePresenter(); - } + addPresenterList(PHONE_LIST_INDEX,phonePresenter); + addPresenterList(HARDWARE_LIST_INDEX,hardwarePresenter); - public void onFragmentPause(){ - IcLog.i(TAG,"onFragmentPause"); - timeDatePresenter.onPausePresenter(); - phonePresenter.onPausePresenter(); + PresenterCycle state = getPresenterList(TIME_LIST_INDEX); + if(state != null){ + ((TimeDatePresenter)state).setAnalogClock(false); + } } - public void onFragmentDestroy(){ - IcLog.i(TAG,"onFragmentDestroy"); - batteryPresenter.unRegisterBatteryReceiver(); - hardwarePresenter.unRegisterHardwareReceiver(); - phonePresenter.onDestroyPresenter(); - timeDatePresenter.unRegisterTimeDateReceiver(); - } public static class Factory extends ViewModelProvider.NewInstanceFactory { @@ -106,47 +51,91 @@ public class L02MainModel extends AndroidViewModel { } } - public LiveData getObsPhoneTypeID() { - return mObsPhoneTypeID; + public LiveData getObservablePhoneType() { + PresenterCycle state = getPresenterList(PHONE_LIST_INDEX); + if(state != null){ + return ((PhoneStatePresenter)state).getPhoneTypeObservable(); + } + return null; } - public LiveData getObsPhoneSignalID() { - return mObsPhoneSignalID; + public LiveData getObservableSignal() { + PresenterCycle state = getPresenterList(PHONE_LIST_INDEX); + if(state != null){ + return ((PhoneStatePresenter)state).getPhoneSignalObservable(); + } + return null; } - public LiveData getObsPhoneTransportID() { - return mObsPhoneTransportID; + public LiveData getObservableTransport() { + PresenterCycle state = getPresenterList(PHONE_LIST_INDEX); + if(state != null){ + return ((PhoneStatePresenter)state).getPhoneTransportObservable(); + } + return null; } - public LiveData getObsBatteryValue() { - return mObsBatteryValue; + public LiveData getObservableBattery() { + PresenterCycle state = getPresenterList(BATTERY_LIST_INDEX); + if(state != null){ + return ((BatteryPresenter)state).getObsBatteryResID(); + } + return null; } - public LiveData getObsBatteryCharging() { - return mObsBatteryCharging; + public LiveData getObservableBatteryCharging() { + PresenterCycle state = getPresenterList(BATTERY_LIST_INDEX); + if(state != null){ + return ((BatteryPresenter)state).getObsBatteryCharging(); + } + return null; } - public LiveData getObsBatteryResID() { - return mObsBatteryResID; + public LiveData getObservableBatteryValue() { + PresenterCycle state = getPresenterList(BATTERY_LIST_INDEX); + if(state != null){ + return ((BatteryPresenter)state).getObsBatteryValue(); + } + return null; } - public LiveData> getObsTime() { - return mObsTime; + public LiveData getObservableHardwareHeart() { + PresenterCycle state = getPresenterList(HARDWARE_LIST_INDEX); + if(state != null){ + return ((HardwarePresenter)state).getObsHardwareHeart(); + } + return null; } - public LiveData getObsYear() { - return mObsYear; + public LiveData getObservableHardwarePed() { + PresenterCycle state = getPresenterList(HARDWARE_LIST_INDEX); + if(state != null){ + return ((HardwarePresenter)state).getObsHardwarePed(); + } + return null; } - public LiveData getObsWeek() { - return mObsWeek; + public LiveData getObservableWeek() { + PresenterCycle state = getPresenterList(TIME_LIST_INDEX); + if(state != null){ + return ((TimeDatePresenter)state).getObsWeek(); + } + return null; } - public LiveData getObsHardwareHeart() { - return mObsHardwareHeart; + public LiveData getObservableYear() { + PresenterCycle state = getPresenterList(TIME_LIST_INDEX); + if(state != null){ + return ((TimeDatePresenter)state).getObsYear(); + } + return null; } - public LiveData getObsHardwarePed() { - return mObsHardwarePed; + public LiveData getObservableTime() { + PresenterCycle state = getPresenterList(TIME_LIST_INDEX); + if(state != null){ + return ((TimeDatePresenter)state).getObsTime(); + } + return null; } } diff --git a/app/src/main/java/com/ic/launcher/mode/LowPowerModel.java b/app/src/main/java/com/ic/launcher/mode/LowPowerModel.java new file mode 100644 index 0000000..6002e43 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/mode/LowPowerModel.java @@ -0,0 +1,66 @@ +package com.ic.launcher.mode; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import com.ic.launcher.presenter.BatteryPresenter; + +public class LowPowerModel extends AndroidViewModel { + + private final BatteryPresenter batteryPresenter; + + private LowPowerModel(Application application) { + super(application); + batteryPresenter = new BatteryPresenter(application); + + } + + public void OnUiCreate() { + if (batteryPresenter != null) { + batteryPresenter.onPresenterCreate(); + } + } + + public void OnUiDestroy() { + if (batteryPresenter != null) { + batteryPresenter.onPresenterDestroy(); + } + } + + public LiveData getObservableLowPowerValue() { + if (batteryPresenter != null) { + return batteryPresenter.getObsLowPowerValue(); + } + return null; + } + + public LiveData getObservableLowPower() { + if (batteryPresenter != null) { + return batteryPresenter.getObsLowPower(); + } + return null; + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + + @NonNull + private final Application mApplication; + + + public Factory(@NonNull Application application) { + mApplication = application; + } + + @SuppressWarnings("unchecked") + @Override + @NonNull + public T create(@NonNull Class modelClass) { + return (T) new LowPowerModel(mApplication); + } + } +} diff --git a/app/src/main/java/com/ic/launcher/presenter/AppListPresenter.java b/app/src/main/java/com/ic/launcher/presenter/AppListPresenter.java index bdc912c..93a152a 100644 --- a/app/src/main/java/com/ic/launcher/presenter/AppListPresenter.java +++ b/app/src/main/java/com/ic/launcher/presenter/AppListPresenter.java @@ -15,7 +15,7 @@ import com.ic.launcher.entity.AppInfoEntity; import java.util.List; -public class AppListPresenter { +public class AppListPresenter{ private Context context; private MutableLiveData> mObsAppInfoList; @@ -24,6 +24,7 @@ public class AppListPresenter { private String mErrorInfo; + public AppListPresenter(Context context) { this.context = context; mObsAppInfoList = new MutableLiveData<>(); diff --git a/app/src/main/java/com/ic/launcher/presenter/BatteryPresenter.java b/app/src/main/java/com/ic/launcher/presenter/BatteryPresenter.java index 4d16b68..23cbc09 100644 --- a/app/src/main/java/com/ic/launcher/presenter/BatteryPresenter.java +++ b/app/src/main/java/com/ic/launcher/presenter/BatteryPresenter.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; +import android.telephony.TelephonyManager; import android.text.TextUtils; import androidx.lifecycle.MediatorLiveData; @@ -13,13 +14,21 @@ import com.ic.launcher.configure.l02.L02Icon; import com.ic.launcher.util.IcLog; -public class BatteryPresenter { +public class BatteryPresenter extends PresenterCycle { private static final String TAG = "BatteryPresenter"; + + private static final int LOW_LEVEL = 15; + private static final int SHUT_DOWN_LEVEL = 5; + private Context mContext; + private boolean isLowPowerState = false; + private MediatorLiveData mObsBatteryValue; private MediatorLiveData mObsBatteryCharging; private MediatorLiveData mObsBatteryResID; + private MediatorLiveData mObsLowPower; + private MediatorLiveData mObsLowPowerValue; public MediatorLiveData getObsBatteryValue() { return mObsBatteryValue; @@ -33,6 +42,28 @@ public class BatteryPresenter { return mObsBatteryResID; } + public MediatorLiveData getObsLowPower() { + return mObsLowPower; + } + + public MediatorLiveData getObsLowPowerValue() { + return mObsLowPowerValue; + } + + @Override + public void onPresenterCreate() { + super.onPresenterCreate(); + IcLog.i(TAG,"BatteryPresenter onPresenterCreate"); + registerBatteryReceiver(); + } + + @Override + public void onPresenterDestroy() { + super.onPresenterDestroy(); + IcLog.i(TAG,"BatteryPresenter onPresenterDestroy"); + unRegisterBatteryReceiver(); + } + public BatteryPresenter(Context context) { mContext = context; @@ -40,23 +71,27 @@ public class BatteryPresenter { mObsBatteryCharging = new MediatorLiveData<>(); mObsBatteryResID = new MediatorLiveData<>(); - registerBatteryReceiver(); + mObsLowPower = new MediatorLiveData<>(); + mObsLowPowerValue = new MediatorLiveData<>(); } + /** + * 注册监听电量改变,充电拔出广播 + */ private void registerBatteryReceiver() { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); - filter.addAction(Intent.ACTION_BATTERY_LOW); - filter.addAction(Intent.ACTION_BATTERY_OKAY); - filter.addAction(Intent.ACTION_POWER_CONNECTED); filter.addAction(Intent.ACTION_POWER_DISCONNECTED); mContext.registerReceiver(mIntentReceiver, filter); } - public void unRegisterBatteryReceiver() { + /** + * 移除广播 + */ + private void unRegisterBatteryReceiver() { try { mContext.unregisterReceiver(mIntentReceiver); - } catch (Exception e) { + } catch (IllegalArgumentException e) { IcLog.e(TAG, "BatteryPresenter", e); } } @@ -72,48 +107,59 @@ public class BatteryPresenter { return; } - IcLog.i(TAG, "Battery Statu:" + acyion); - switch (acyion) { case Intent.ACTION_BATTERY_CHANGED: + IcLog.i(TAG, "Battery Statu: ACTION_BATTERY_CHANGED"); int status = intent.getIntExtra("status", -1); int rawlevel = intent.getIntExtra("level", -1); int scale = intent.getIntExtra("scale", -1); - updateBatteryValue(rawlevel, scale); - updateBatteryCharging(status); - break; - case Intent.ACTION_BATTERY_OKAY: - mObsBatteryCharging.setValue(false); - IcLog.i(TAG, "POWER ACTION_BATTERY_OKAY"); + updateBatteryValue(rawlevel, scale, status); break; case Intent.ACTION_POWER_DISCONNECTED: - //电量满了,或者 没有接电源 + // 没有接电源 mObsBatteryCharging.setValue(false); IcLog.i(TAG, "POWER ACTION_POWER_DISCONNECTED"); break; - case Intent.ACTION_POWER_CONNECTED: - IcLog.i(TAG, "POWER CONNECTED"); - break; } } } }; - private void updateBatteryValue(int rawlevel, int scale) { - int level = -1; // percentage, or -1 for unknown + private void updateBatteryValue(int rawlevel, int scale, int status) { + int level = -1; if (rawlevel >= 0 && scale > 0) { level = (rawlevel * 100) / scale; } + IcLog.i(TAG, "Battery Value:" + level); + + if (level == -1) return; + + //低于5 则直接关机 + if (level <= SHUT_DOWN_LEVEL) { + shutDown(); + } else if (level <= LOW_LEVEL) { + //进入低电量 + if(!gotoLowPowerMode(level)){ + updateBatteryObserveValue(level,status); + } + } else { + //退出低电量模式 + if (isLowPowerState) { + mObsLowPower.setValue(false); + isLowPowerState = false; + } + updateBatteryObserveValue(level,status); + } + } + private void updateBatteryObserveValue(int level,int status){ mObsBatteryResID.setValue(L02Icon.l02BatteryResId[getBatteryLevel(level)]); mObsBatteryValue.setValue(level + "%"); - } - private void updateBatteryCharging(int state) { - if (BatteryManager.BATTERY_STATUS_CHARGING == state) { + if (BatteryManager.BATTERY_STATUS_CHARGING == status) { mObsBatteryCharging.setValue(true); - }else{ + } else { mObsBatteryCharging.setValue(false); } } @@ -134,4 +180,49 @@ public class BatteryPresenter { return index; } + + private boolean gotoLowPowerMode(int level) { + //判断是否在通话中,如果是 则返回 + if (phoneIsInUse()) return false; + + //是否是首次进入到低电量模式 + if (!isLowPowerState) { + mObsLowPower.setValue(true); + getHome(); + isLowPowerState = true; + } + + //更新低电量的值 + mObsLowPowerValue.setValue(level + "%"); + + return true; + } + + private void getHome() { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addCategory(Intent.CATEGORY_HOME); + mContext.startActivity(intent); + } + + private boolean phoneIsInUse() { + TelephonyManager mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + if (mTelephonyManager == null) { + return false; + } + int state = mTelephonyManager.getCallState(); + return state != TelephonyManager.CALL_STATE_IDLE; + } + + + private void shutDown() { + try { + Intent intent = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN"); + intent.putExtra("android.intent.extra.KEY_CONFIRM", false); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mContext.startActivity(intent); + } catch (Exception e) { + IcLog.e(TAG, "shutdown", e); + } + } } diff --git a/app/src/main/java/com/ic/launcher/presenter/HardwarePresenter.java b/app/src/main/java/com/ic/launcher/presenter/HardwarePresenter.java index d1441b0..148ae14 100644 --- a/app/src/main/java/com/ic/launcher/presenter/HardwarePresenter.java +++ b/app/src/main/java/com/ic/launcher/presenter/HardwarePresenter.java @@ -11,7 +11,7 @@ import androidx.lifecycle.MediatorLiveData; import com.ic.launcher.util.IcLog; import com.ic.launcher.util.SPUtils; -public class HardwarePresenter { +public class HardwarePresenter extends PresenterCycle { private static final String TAG = "HardwarePresenter"; private static final String HEART_ACTION = "com.ic.action.BLOOD_HEART"; @@ -23,14 +23,28 @@ public class HardwarePresenter { private MediatorLiveData mObsHardwareHeart; private MediatorLiveData mObsHardwarePed; - public HardwarePresenter(Context context) { + @Override + public void onPresenterCreate() { + super.onPresenterCreate(); + registerHardwareBroadcast(); + } - this.mContext = context; + @Override + public void onPresenterResume() { + super.onPresenterResume(); + sendGetPedBroadcast(); + } + @Override + public void onPresenterDestroy() { + super.onPresenterDestroy(); + unRegisterHardwareReceiver(); + } + + public HardwarePresenter(Context context) { + this.mContext = context; mObsHardwareHeart = new MediatorLiveData<>(); mObsHardwarePed = new MediatorLiveData<>(); - - registerHardwareBroadcast(); } public MediatorLiveData getObsHardwareHeart() { @@ -41,6 +55,12 @@ public class HardwarePresenter { return mObsHardwarePed; } + private void sendGetPedBroadcast(){ + Intent pedIntent = new Intent(); + pedIntent.setAction(GET_PED_ACTION); + mContext.sendBroadcast(pedIntent); + } + private void registerHardwareBroadcast() { IntentFilter filter = new IntentFilter(); filter.addAction(PED_ACTION); @@ -48,20 +68,14 @@ public class HardwarePresenter { mContext.registerReceiver(mIntentReceiver, filter); } - public void unRegisterHardwareReceiver() { + private void unRegisterHardwareReceiver() { try { mContext.unregisterReceiver(mIntentReceiver); - }catch (Exception e){ + }catch (IllegalArgumentException e){ IcLog.e(TAG,"HardwareReceiver",e); } } - public void sendGetPedBroadcast(){ - Intent pedIntent = new Intent(); - pedIntent.setAction(GET_PED_ACTION); - mContext.sendBroadcast(pedIntent); - } - private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { diff --git a/app/src/main/java/com/ic/launcher/presenter/PhoneStatePresenter.java b/app/src/main/java/com/ic/launcher/presenter/PhoneStatePresenter.java index 8d854d7..896ffba 100644 --- a/app/src/main/java/com/ic/launcher/presenter/PhoneStatePresenter.java +++ b/app/src/main/java/com/ic/launcher/presenter/PhoneStatePresenter.java @@ -6,7 +6,7 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MediatorLiveData; -public class PhoneStatePresenter { +public class PhoneStatePresenter extends PresenterCycle { private static final String TAG = "PhoneStatePresenter"; private QueryPhoneState queryState; @@ -17,27 +17,9 @@ public class PhoneStatePresenter { private MediatorLiveData mObsPhoneTypeID; private MediatorLiveData mObsPhoneSignalID; - public PhoneStatePresenter(Context context) { - mObsPhoneTypeID = new MediatorLiveData<>(); - mObsPhoneSignalID = new MediatorLiveData<>(); - mObsPhoneTransportID = new MediatorLiveData<>(); - - queryState = new QueryPhoneState(context,mObsPhoneTypeID,mObsPhoneSignalID,mObsPhoneTransportID); - } - - public LiveData getPhoneTypeObservable() { - return mObsPhoneTypeID; - } - - public LiveData getPhoneSignalObservable() { - return mObsPhoneSignalID; - } - - public LiveData getPhoneTransportObservable() { - return mObsPhoneTransportID; - } - - public void onResumePresenter() { + @Override + public void onPresenterResume() { + super.onPresenterResume(); if(mQueryThread == null){ mQueryThread = new Thread(queryState); mQueryThread.start(); @@ -46,20 +28,46 @@ public class PhoneStatePresenter { } } - public void onPausePresenter() { + @Override + public void onPresenterPause() { + super.onPresenterPause(); if (mQueryThread != null && queryState != null) { queryState.pauseQueryThread(); } } - public void onDestroyPresenter() { + @Override + public void onPresenterDestroy() { + super.onPresenterDestroy(); if (mQueryThread != null) { mQueryThread.interrupt(); } mQueryThread = null; - queryState.destroyPhoneState(); + if(queryState != null){ + queryState.destroyPhoneState(); + } queryState=null; } + + public PhoneStatePresenter(Context context) { + mObsPhoneTypeID = new MediatorLiveData<>(); + mObsPhoneSignalID = new MediatorLiveData<>(); + mObsPhoneTransportID = new MediatorLiveData<>(); + + queryState = new QueryPhoneState(context,mObsPhoneTypeID,mObsPhoneSignalID,mObsPhoneTransportID); + } + + public LiveData getPhoneTypeObservable() { + return mObsPhoneTypeID; + } + + public LiveData getPhoneSignalObservable() { + return mObsPhoneSignalID; + } + + public LiveData getPhoneTransportObservable() { + return mObsPhoneTransportID; + } } diff --git a/app/src/main/java/com/ic/launcher/presenter/PresenterCycle.java b/app/src/main/java/com/ic/launcher/presenter/PresenterCycle.java new file mode 100644 index 0000000..89cec58 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/presenter/PresenterCycle.java @@ -0,0 +1,16 @@ +package com.ic.launcher.presenter; + +public abstract class PresenterCycle { + + public void onPresenterCreate() { + } + + public void onPresenterResume() { + } + + public void onPresenterPause() { + } + + public void onPresenterDestroy() { + } +} diff --git a/app/src/main/java/com/ic/launcher/presenter/QueryPhoneState.java b/app/src/main/java/com/ic/launcher/presenter/QueryPhoneState.java index c5e8320..00d96c3 100644 --- a/app/src/main/java/com/ic/launcher/presenter/QueryPhoneState.java +++ b/app/src/main/java/com/ic/launcher/presenter/QueryPhoneState.java @@ -127,7 +127,7 @@ public class QueryPhoneState extends QueryThread { if (cellInfo instanceof CellInfoLte) { // cast to CellInfoLte and call all the CellInfoLte methods you need int level = ((CellInfoLte) cellInfo).getCellSignalStrength().getLevel() + 1; - IcLog.i(TAG, "Signal Strength level:" + level); + //IcLog.i(TAG, "Signal Strength level:" + level); if (level != oldSignalLevel) { oldSignalLevel = level; mObsPhoneSignalID.postValue(l02SignalResId[level + 1]); diff --git a/app/src/main/java/com/ic/launcher/presenter/QueryThread.java b/app/src/main/java/com/ic/launcher/presenter/QueryThread.java index 922dd9b..a90b73a 100644 --- a/app/src/main/java/com/ic/launcher/presenter/QueryThread.java +++ b/app/src/main/java/com/ic/launcher/presenter/QueryThread.java @@ -3,7 +3,7 @@ package com.ic.launcher.presenter; import com.ic.launcher.util.IcLog; public abstract class QueryThread extends Thread { - private static final String TAG="QueryThread"; + private static final String TAG = "QueryThread"; private final Object lock = new Object(); private boolean pause = false; @@ -32,6 +32,9 @@ public abstract class QueryThread extends Thread { } } + /**** + * 此处时间不能乱修改,模拟表盘 秒表也用。所以要修改请{@link TimeDatePresenter} 一起修改 + */ @Override public void run() { super.run(); diff --git a/app/src/main/java/com/ic/launcher/presenter/TimeDatePresenter.java b/app/src/main/java/com/ic/launcher/presenter/TimeDatePresenter.java index f44de06..0d3abd6 100644 --- a/app/src/main/java/com/ic/launcher/presenter/TimeDatePresenter.java +++ b/app/src/main/java/com/ic/launcher/presenter/TimeDatePresenter.java @@ -5,51 +5,108 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.text.format.DateFormat; +import android.content.pm.PackageManager; +import android.os.Handler; +import android.os.Message; +import android.text.TextUtils; +import androidx.annotation.NonNull; import androidx.lifecycle.MediatorLiveData; import com.ic.launcher.util.IcLog; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.TimeZone; +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.lang.ref.WeakReference; +import java.util.Locale; + import static com.ic.launcher.configure.l02.L02Icon.l02TimeHourImage; import static com.ic.launcher.configure.l02.L02Icon.l02TimeMinutesImage; -public class TimeDatePresenter { +public class TimeDatePresenter extends PresenterCycle { private static final String TAG = "TimeDatePresenter"; + private static final DateTimeFormatter MMDD = DateTimeFormatter.ofPattern("MM-dd"); - private static final CharSequence DEFAULT_FORMAT_24_HOUR = "HH:mm"; - private static final CharSequence DEFAULT_FORMAT_MM_DD = "MM-dd"; - private static final CharSequence DEFAULT_FORMAT_EEEEE = "EEEE"; - - private MediatorLiveData> mObsTime; + private MediatorLiveData mObsTime; private MediatorLiveData mObsYear; private MediatorLiveData mObsWeek; + private MediatorLiveData mObsHourList; private Context mContext; - private Calendar mTime; - private boolean mShouldRunTicker = false; - private ArrayList timeList; + private Thread loopThread = null; + private LoopSecondThread mLoopSecond = null; + + private boolean mAnalogClock=false; + private SecondMessage secondMessage; + + @Override + public void onPresenterCreate() { + super.onPresenterCreate(); + registerTimeDateReceiver(); + } + + @Override + public void onPresenterResume() { + super.onPresenterResume(); + //如果获取秒钟的线程没有启动。则启动 + if (mAnalogClock) { + if (loopThread == null || mLoopSecond == null) { + mLoopSecond = new LoopSecondThread(); + loopThread = new Thread(mLoopSecond); + loopThread.start(); + } else { + mLoopSecond.resumeQueryThread(); + } + } + } + + @Override + public void onPresenterPause() { + super.onPresenterPause(); + if (mAnalogClock) { + if (mLoopSecond != null) { + mLoopSecond.pauseQueryThread(); + } + } + } + + @Override + public void onPresenterDestroy() { + super.onPresenterDestroy(); + unRegisterTimeDateReceiver(); + + if (loopThread != null) { + loopThread.interrupt(); + } + } + + public void setAnalogClock(boolean analog) { + this.mAnalogClock = analog; + } public TimeDatePresenter(Context context) { mContext = context; - timeList = new ArrayList<>(); - createTime(null); mObsTime = new MediatorLiveData<>(); mObsYear = new MediatorLiveData<>(); mObsWeek = new MediatorLiveData<>(); - registerTimeDateReceiver(); + mObsHourList = new MediatorLiveData<>(); + + secondMessage = new SecondMessage(this); + + analysisDataTimeValue(null); } - public MediatorLiveData> getObsTime() { + public MediatorLiveData getObsTime() { return mObsTime; } @@ -57,18 +114,14 @@ public class TimeDatePresenter { return mObsYear; } - public MediatorLiveData getmObsWeek() { + public MediatorLiveData getObsWeek() { return mObsWeek; } - public void onResumePresenter() { - onTimeChanged(); - mShouldRunTicker = true; + public MediatorLiveData getObsHourList() { + return mObsHourList; } - public void onPausePresenter() { - mShouldRunTicker = false; - } private void registerTimeDateReceiver() { IntentFilter filter = new IntentFilter(); @@ -78,10 +131,10 @@ public class TimeDatePresenter { mContext.registerReceiver(mIntentReceiver, filter); } - public void unRegisterTimeDateReceiver() { + private void unRegisterTimeDateReceiver() { try { mContext.unregisterReceiver(mIntentReceiver); - } catch (Exception e) { + } catch (IllegalArgumentException e) { IcLog.e(TAG, "unRegisterTimeDateReceiver", e); } } @@ -89,53 +142,81 @@ public class TimeDatePresenter { private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { - final String timeZone = intent.getStringExtra("time-zone"); - createTime(timeZone); - } else if (!mShouldRunTicker && (Intent.ACTION_TIME_TICK.equals(intent.getAction()) - || Intent.ACTION_TIME_CHANGED.equals(intent.getAction()))) { - return; + String action = intent.getAction(); + if (TextUtils.isEmpty(action)) return; + + if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { + analysisDataTimeValue(intent.getStringExtra("time-zone")); + } else { + analysisDataTimeValue(null); } - onTimeChanged(); } }; - private void createTime(String timeZone) { - if (timeZone != null) { - mTime = Calendar.getInstance(TimeZone.getTimeZone(timeZone)); + 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 { - mTime = Calendar.getInstance(); + currDateTime = LocalDateTime.now(ZoneId.systemDefault()); + } + + + if (mAnalogClock) { + updateAnalogClock(currDateTime); + } else { + //如果当前是数字表盘 + computeMainClockTime(currDateTime); } } - private void onTimeChanged() { - mTime.setTimeInMillis(System.currentTimeMillis()); + private void computeMainClockTime(LocalDateTime localDateTime) { - CharSequence time = DateFormat.format(DEFAULT_FORMAT_24_HOUR, mTime); - CharSequence mmdd = DateFormat.format(DEFAULT_FORMAT_MM_DD, mTime); - CharSequence week = DateFormat.format(DEFAULT_FORMAT_EEEEE, mTime); + mObsYear.setValue(localDateTime.format(MMDD)); - timeList.clear(); + mObsWeek.setValue(localDateTime.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault())); - boolean isHour = true; + int hour = localDateTime.getHour(); + int minute = localDateTime.getMinute(); - for (int i = 0; i < time.length(); i++) { - if (time.charAt(i) == ':') { - isHour = false; - continue; - } + mObsTime.setValue(new int[]{ + l02TimeHourImage[hour / 10], + l02TimeHourImage[hour % 10], + l02TimeMinutesImage[minute / 10], + l02TimeMinutesImage[minute % 10]}); + } - if (isHour) { - timeList.add(l02TimeHourImage[Character.getNumericValue(time.charAt(i))]); - } else { - timeList.add(l02TimeMinutesImage[Character.getNumericValue(time.charAt(i))]); - } + private void updateAnalogClock(LocalDateTime localDateTime) { + //模拟表盘 + mObsHourList.setValue(new int[]{ + localDateTime.getHour(), + localDateTime.getMinute(), + localDateTime.getSecond()}); + } + + private static class SecondMessage extends Handler{ + private WeakReference reference; + + public SecondMessage(TimeDatePresenter ref) { + this.reference = new WeakReference(ref) ; } - mObsTime.setValue(timeList); - mObsYear.setValue(mmdd.toString()); - mObsWeek.setValue(week.toString()); + @Override + public void dispatchMessage(@NonNull Message msg) { + super.dispatchMessage(msg); + reference.get().analysisDataTimeValue(null); + } + } - IcLog.i(TAG, "time" + time.toString() + " mmdd:" + mmdd.toString() + " week" + week.toString()); + private class LoopSecondThread extends QueryThread { + @Override + void onThreadExecute() { + if(secondMessage != null){ + secondMessage.sendEmptyMessage(1); + } + } } } diff --git a/app/src/main/java/com/ic/launcher/util/SPUtils.java b/app/src/main/java/com/ic/launcher/util/SPUtils.java index 9cae414..22b92f7 100644 --- a/app/src/main/java/com/ic/launcher/util/SPUtils.java +++ b/app/src/main/java/com/ic/launcher/util/SPUtils.java @@ -7,7 +7,7 @@ public class SPUtils { private static final String Blood_Heart = "Blood_Heart"; - public static SharedPreferences getSP(Context context) { + private static SharedPreferences getSP(Context context) { return context.getSharedPreferences("IcBloodSet", Context.MODE_PRIVATE); } @@ -23,4 +23,23 @@ public class SPUtils { 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/launcher/widget/ClockDrawableView.java b/app/src/main/java/com/ic/launcher/widget/ClockDrawableView.java new file mode 100644 index 0000000..66d3ba2 --- /dev/null +++ b/app/src/main/java/com/ic/launcher/widget/ClockDrawableView.java @@ -0,0 +1,122 @@ +package com.ic.launcher.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.View; + +import androidx.core.content.ContextCompat; + +import com.ic.launcher.R; + + +public class ClockDrawableView extends View { + + private Drawable mHourHand; + private Drawable mMinuteHand; + private Drawable mSecondHead; + + private int mDialWidth; + private int mDialHeight; + + + private float mMinutes; + private float mHour; + private float mSecond; + + private int rX; + private int rY; + + public ClockDrawableView(Context context) { + this(context, null); + } + + public ClockDrawableView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ClockDrawableView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ClockDrawableView,defStyleAttr,0); + + int dialResId = typedArray.getResourceId(R.styleable.ClockDrawableView_mBackgroundClock,-1); + int hourResId = typedArray.getResourceId(R.styleable.ClockDrawableView_mHourHandClock,-1); + int minuteResId = typedArray.getResourceId(R.styleable.ClockDrawableView_mMinuteHandClock,-1); + int secondResId = typedArray.getResourceId(R.styleable.ClockDrawableView_mSecondHandClock,-1); + + Drawable mDial =ContextCompat.getDrawable(context,dialResId); + mHourHand = ContextCompat.getDrawable(context,hourResId); + mMinuteHand = ContextCompat.getDrawable(context,minuteResId); + mSecondHead = ContextCompat.getDrawable(context,secondResId); + + typedArray.recycle(); + + if(mDial != null){ + mDialWidth = mDial.getIntrinsicWidth(); + mDialHeight = mDial.getIntrinsicHeight(); + + rX = mDialWidth / 2; + rY = mDialHeight / 2; + } + } + + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + + float hScale = 1.0f; + float vScale = 1.0f; + + if (widthMode != MeasureSpec.UNSPECIFIED && widthSize < mDialWidth) { + hScale = (float) widthSize / (float) mDialWidth; + } + + if (heightMode != MeasureSpec.UNSPECIFIED && heightSize < mDialHeight) { + vScale = (float) heightSize / (float) mDialHeight; + } + + float scale = Math.min(hScale, vScale); + + setMeasuredDimension(resolveSizeAndState((int) (mDialWidth * scale), widthMeasureSpec, 0), + resolveSizeAndState((int) (mDialHeight * scale), heightMeasureSpec, 0)); + } + + + private void drawCustomDrawable(Canvas canvas, Drawable drawable, int rx, int ry, float value) { + canvas.save(); + canvas.rotate(value, rx, ry); + int w = drawable.getIntrinsicWidth(); + int h = drawable.getIntrinsicHeight(); + drawable.setBounds(rx - (w / 2), ry - (h / 2), rx + (w / 2), ry + (h / 2)); + drawable.draw(canvas); + canvas.restore(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + //绘制小时 + drawCustomDrawable(canvas, mHourHand, rX, rY, mHour / 12.0f * 360.0f); + //绘制分钟 + drawCustomDrawable(canvas, mMinuteHand, rX, rY, mMinutes / 60.0f * 360.0f); + //绘制秒钟 + drawCustomDrawable(canvas, mSecondHead, rX, rY, mSecond / 60.0f * 360.0f); + } + + public void onTimeChanged(int hour, int minute, int second) { + + mMinutes = minute + second / 60.0f; + mHour = hour + mMinutes / 60.0f; + mSecond = second; + + invalidate(); + } +} diff --git a/app/src/main/java/com/ic/launcher/widget/ClockWatchView.java b/app/src/main/java/com/ic/launcher/widget/ClockWatchView.java deleted file mode 100644 index bd8e8b6..0000000 --- a/app/src/main/java/com/ic/launcher/widget/ClockWatchView.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.ic.launcher.widget; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Rect; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.View; - -import androidx.annotation.Nullable; - -public class ClockWatchView extends View { - - private float mRadius; //外圆半径 - - private int mColorLong = Color.WHITE; //长线的颜色 - private int mColorShort = Color.WHITE; //短线的颜色 - - //指针末尾的长度 - private float mPointEndLength; - - private Paint mPaint; - - public ClockWatchView(Context context) { - this(context, null); - } - - public ClockWatchView(Context context, @Nullable AttributeSet attrs) { - this(context, null, 0); - } - - public ClockWatchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - //初始化画笔 - init(); - } - - private void init() { - mPaint = new Paint(); - mPaint.setAntiAlias(true); - mPaint.setDither(true); - } - - @Override - protected void onDraw(Canvas canvas) { - canvas.save(); - - //移动到中心部分 - canvas.translate(getWidth() / 2, getHeight() / 2); - - //绘制刻度 - paintScale(canvas); - - canvas.restore(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - - int widthSize = MeasureSpec.getSize(widthMeasureSpec); - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - int heightSize = MeasureSpec.getSize(heightMeasureSpec); - int heightMode = MeasureSpec.getMode(heightMeasureSpec); - - - if (widthMode == MeasureSpec.AT_MOST - || widthMode == MeasureSpec.UNSPECIFIED - || heightMeasureSpec == MeasureSpec.AT_MOST - || heightMeasureSpec == MeasureSpec.UNSPECIFIED) { - //宽度高度至少有一个确定的值,不能同时为wrap_content - return; - } else { //至少有一个为确定值,要获取其中的最小值 - if (widthMode == MeasureSpec.EXACTLY) { - setMeasuredDimension(widthSize, heightSize); - } - } - } - - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - mRadius = (Math.min(w, h)) / 2; - mPointEndLength = mRadius / 6; - } - - private void paintScale(Canvas canvas) { - //设置宽度 - mPaint.setStrokeWidth(dpToPx(1)); - int lineWidth = 0; - for (int i = 0; i < 60; i++) { - if (i % 5 == 0) { //整点 - mPaint.setStrokeWidth(dpToPx(2f)); - mPaint.setColor(mColorLong); - lineWidth = 8; - mPaint.setTextSize(spToPx(26)); - String text = ((i / 5) == 0 ? 12 : (i / 5)) + ""; - Rect textBound = new Rect(); - mPaint.getTextBounds(text, 0, text.length(), textBound); - mPaint.setColor(Color.WHITE); - canvas.save(); - if (i > 15 && i < 45) { - canvas.translate(0, -mRadius + lineWidth - dpToPx(5) + (textBound.bottom - textBound.top)); - } else if (i == 15 || i == 45) { - canvas.translate(0, -mRadius + lineWidth - dpToPx(8) + (textBound.bottom - textBound.top)); - } else { - canvas.translate(0, -mRadius + lineWidth + dpToPx(2) + (textBound.bottom - textBound.top)); - } - canvas.rotate(-6 * i); - mPaint.setStyle(Paint.Style.FILL); - canvas.drawText(text, -(textBound.right - textBound.left) / 2, textBound.bottom+dpToPx(6) , mPaint); - canvas.restore(); - } else { //非整点 - lineWidth = 4; - mPaint.setColor(mColorShort); - mPaint.setStrokeWidth(dpToPx(0.5f)); - } - canvas.drawLine(0, -mRadius, 0, -mRadius + lineWidth, mPaint); - canvas.rotate(6); - } - canvas.restore(); - } - - private float dpToPx(float dp) { - return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); - } - - private float spToPx(float sp) { - return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics()); - } -} diff --git a/app/src/main/java/com/ic/launcher/widget/WidgetTimeImageView.java b/app/src/main/java/com/ic/launcher/widget/WidgetTimeImageView.java index 4a8feca..83b83a8 100644 --- a/app/src/main/java/com/ic/launcher/widget/WidgetTimeImageView.java +++ b/app/src/main/java/com/ic/launcher/widget/WidgetTimeImageView.java @@ -41,17 +41,26 @@ public class WidgetTimeImageView extends RelativeLayout { mImageView[3] = (ImageView) view.findViewById(R.id.time_minute_bit); } - private void updateTime(ArrayList timeRes) { + private void updateTime(int hourTen,int hourBit,int minuteTen,int minuteBit) { - if (timeRes == null || timeRes.size() == 0 || timeRes.size() != oldTimeArray.length) { - return; + if(hourTen != oldTimeArray[0]){ + mImageView[0].setImageResource(hourTen); + oldTimeArray[0]=hourTen; } - for (int i = 0; i < timeRes.size(); i++) { - if (oldTimeArray[i] != timeRes.get(i)) { - mImageView[i].setImageResource(timeRes.get(i)); - oldTimeArray[i] = timeRes.get(i); - } + if(hourBit != oldTimeArray[1]){ + mImageView[1].setImageResource(hourBit); + oldTimeArray[1]=hourTen; + } + + if(minuteTen != oldTimeArray[2]){ + mImageView[2].setImageResource(minuteTen); + oldTimeArray[2]=minuteTen; + } + + if(minuteBit != oldTimeArray[3]){ + mImageView[3].setImageResource(minuteBit); + oldTimeArray[3]=minuteBit; } if (!isShowColon) { @@ -60,10 +69,10 @@ public class WidgetTimeImageView extends RelativeLayout { } } - @BindingAdapter(value = {"app:timeImageResId"}, requireAll = false) - public static void updateTimeImge(WidgetTimeImageView view, ArrayList timeRes) { + @BindingAdapter(value = {"app:hourTenResId","app:hourBitResId","app:minuteTenResId","app:minuteBitResId"}, requireAll = false) + public static void updateTimeImage(WidgetTimeImageView view, int hourTen,int hourBit,int minuteTen,int minuteBit) { if (view != null) { - view.updateTime(timeRes); + view.updateTime(hourTen,hourBit,minuteTen,minuteBit); } } } diff --git a/app/src/main/res/layout/activity_select_dial.xml b/app/src/main/res/layout/activity_select_dial.xml new file mode 100644 index 0000000..0feb6e2 --- /dev/null +++ b/app/src/main/res/layout/activity_select_dial.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_app_list.xml b/app/src/main/res/layout/fragment_app_list.xml index 9def55e..fe75f5b 100644 --- a/app/src/main/res/layout/fragment_app_list.xml +++ b/app/src/main/res/layout/fragment_app_list.xml @@ -13,7 +13,7 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_clock_6_dial.xml b/app/src/main/res/layout/fragment_clock_6_dial.xml new file mode 100644 index 0000000..8f7fa81 --- /dev/null +++ b/app/src/main/res/layout/fragment_clock_6_dial.xml @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_l02_main.xml b/app/src/main/res/layout/fragment_l02_main.xml index c5857e7..ba6d674 100644 --- a/app/src/main/res/layout/fragment_l02_main.xml +++ b/app/src/main/res/layout/fragment_l02_main.xml @@ -1,22 +1,159 @@ - - - + tools:context=".fragment.l02.L02StatusBarFragment"> + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + android:layout_height="match_parent"> + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_l02_status_bar.xml b/app/src/main/res/layout/fragment_l02_status_bar.xml deleted file mode 100644 index 2ccb81d..0000000 --- a/app/src/main/res/layout/fragment_l02_status_bar.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_l02_watch.xml b/app/src/main/res/layout/fragment_l02_watch.xml deleted file mode 100644 index e71fdca..0000000 --- a/app/src/main/res/layout/fragment_l02_watch.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_low_power_mode.xml b/app/src/main/res/layout/fragment_low_power_mode.xml new file mode 100644 index 0000000..dce1951 --- /dev/null +++ b/app/src/main/res/layout/fragment_low_power_mode.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_select_clock_dial.xml b/app/src/main/res/layout/fragment_select_clock_dial.xml new file mode 100644 index 0000000..bafa4d4 --- /dev/null +++ b/app/src/main/res/layout/fragment_select_clock_dial.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_watch_preview.xml b/app/src/main/res/layout/item_watch_preview.xml new file mode 100644 index 0000000..3910c06 --- /dev/null +++ b/app/src/main/res/layout/item_watch_preview.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/mipmap-ldpi/clock12_dial_preview.png b/app/src/main/res/mipmap-ldpi/clock12_dial_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..eea0cde151ffac8b081ea0bdcf85a8fded980233 GIT binary patch literal 8804 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 P|9z+^Xvo*dT7>;S6zox0 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-ldpi/clock6_dial_preview.png b/app/src/main/res/mipmap-ldpi/clock6_dial_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..e3da0252aacfd46e72c2336cb78490b9ecd0f4d8 GIT binary patch literal 9230 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

js4u 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/clock12_dial.png b/app/src/main/res/mipmap-mdpi/clock12_dial.png new file mode 100644 index 0000000000000000000000000000000000000000..482840aab7ba856bf08cb563e6b14450a0be71da GIT binary patch literal 4972 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 Kcqa7J^Zx=(0QCO= literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/clock12_hand_minute.png b/app/src/main/res/mipmap-mdpi/clock12_hand_minute.png new file mode 100644 index 0000000000000000000000000000000000000000..7520b10b61c944ae57632a7f71eca4e6e225cfdd GIT binary patch literal 1969 zcmd5-TWB0r7@pW|iP2&OgE_8~-JeQ;oA z&N=h{-~avJ|NqRJLxV4D?%Li(5X9#EUbRRN9hvCv+=Ndq9)EupzqXc z(QA4-B=e3|hDE5E6R&&?Qv|W$s9hRH!-ai{;W=?FvWeFmAA1u-YERAAj8TY49hPl3 zP5m-|o+52CO&v%SK*7(#ioJI-fcqy0OUC4=A)C~m=gCw}!2k|K8d-D3+)$~dsRpis z*U>RUkqr|xnx>khh6_Vv)(aq+h$m?SBt=q`<7`3{1#vgY0XD$^p5Xz_@rnQxfg@Kg z3P%e}ODU?kl~{O}rYZ>e3d2;Z)p(VUdqJ6DWm#qb$8a2tE$DEc9(tsf{d#B7uo0~;4b8&f@F+<`92t7!^lAh#f0C4Jf1!>vjbVCvnItOtMO@H$t{hED>PjDW7i;kl6 zEaW*8&@u~6nq{F#%a)R{l_>S#e1&r^U0 z=h5#_2G8SCUhOT_Zv1>beQa^$sn;$~>)nUX&GnzD&-*)O-gxe#aL3$NMJG1@)9a@@ z|IEy)C&Jr{`@T83ti893>Z*5df1B8nAv$7hKiWsY6dr82GX3F?AAFx7ww-VmKK|?- z`G>w^ojsS%eWo@r9nzyFIh-4xAglSlrz{LGcxPj6j6%eM1x0Q@H+;9{)H=IE(`r7~H+|Lxri zXJ0*7xp^&yM&4rX9J)I5srZ;P@T9i!iylxX9_b|8e6){%Db$Hm|ECW7CvpFE1!I?D gZOYrI&*!O)Tk-gHv*%x;dZV9czJE}i>l>N*3lpE(djJ3c literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/clock12_hand_second.png b/app/src/main/res/mipmap-mdpi/clock12_hand_second.png new file mode 100644 index 0000000000000000000000000000000000000000..5339839885e4a39e9e1c7f3e2432641340ee79f5 GIT binary patch literal 1892 zcmb_dO^D<~6wbKo%rMN#cu{m&DAOP-n9hHvD|EX(lXSZ+_Bi%5?jZh5C8^BBnWSP; zvz-}58WCg}r*o%S+9{t(Fx(7i)FCG?I6ub!H4~pQypGyBZho0S)Hjt$1<$K@z z-mCY>g|*cOPb}QMz;WD(=2^SVaWl32o}Xow&tJRv7JJ=A>l<{P__T`>%q@Gw!JrwU zE!@V)+kf^`T;aH5F9n?qy3u;rbV*o5Ii{F}G4tlQ%9$)i?hdBF!COI8<$wC%5)T5e z%AeC)QY*Ibc5wC}!RrUB9rs|zg&u$A0Z_?IMi63(Ko;&sshL&zKCj8vxmn~vA3}Gk z{6N%3YYkW=!9XvT1Xn5VI3;_D%g)0ujGS5R zt{*4|GBxHSNx%*T?b^iM3voo7c9myeieBKEzNfk>ahZhBvSOoOa#oCN2w*GNbR`gJyg2^zGrp+ngz z3r<;f1zpy3!C^K5I=U)ro+Lq3=7;{?q52K_lv!9F@koy8s4`X+PZFSvJwcW+Bl2A& zc$!+)UCnopq4FY=DCVtmsFg-0)}Q%uJQ!><9xWWPc}m#e{Po?hU$J>S-?W!I+0`Gu zmKS=`V(rnwM}J@Z?Wr%9=dM(*d^mUN3G0v9xq^CU@72c&-0`IvH#7OM`OxM0)3^Wf z{O{|x?e?_ypPYN<+T|Bsu75k5J^k@}GtRNeUSqoBU(6rHJjNUy{1D{Oayr5z^89c7 zHSQJerexnx>kaC6(?N#7-lda`+M9n?&|>GpXWFd`(Y3dq`|+Mq?dnqH-fvC<(Bp2I vpZYO9!$88+LWTtYOH$L<=I8I1Ho13C-SNrei*LN1|M!~pRr{Tl%@_Xx!5p%0 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/clock6_dial.png b/app/src/main/res/mipmap-mdpi/clock6_dial.png new file mode 100644 index 0000000000000000000000000000000000000000..02d621787b86ddbef307b88265e13f6a3b109559 GIT binary patch literal 6182 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 VCYP1FWAOQmih`zmv7FiS{{fefOz;2z literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/clock6_hand_cap.png b/app/src/main/res/mipmap-mdpi/clock6_hand_cap.png new file mode 100644 index 0000000000000000000000000000000000000000..a21be4d3f326146214cc1ba0d0aa893439830760 GIT binary patch literal 1199 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/clock6_hand_minute.png b/app/src/main/res/mipmap-mdpi/clock6_hand_minute.png new file mode 100644 index 0000000000000000000000000000000000000000..1de66fa241e8c653a27a3943308ed582fed664b4 GIT binary patch literal 1112 zcmaJ=O=#0#7!EpgP6m40ycjbN{w&R3(>7ssv`Omi-*7v49P{Wv4}R&|%|l%v`F`>|@B6%e^JAIwy*>MZOFv2!P!5(*RdWFmGhh*rDNCCIS)dv9nI$kp5c_R2 zUqFTQ1zCqyK=Uzyn&n_NK@1Jo98IqPL>9r6X-BD_&tFocX+)`UG0mnO1(eN^h6{3y zOkQtPbjhHG&yhnl85^(w(#V=MZF_PpN;U1uc<)~`6xoEJN|f3bRY;GK3UmP}212yX zhQef63UFdL91IVVJj;m;D=-2}^MV{?Nm+ulIif(ks{H63I^oAfPeML3J16jr(&g5{*sJBDqq zl_;DtrlvUz7hoC7^5bfvJ(LBzGCHEYeBA*|7I<*h)p0#a18p+S-QJFTAXX!fx+X4) zHmyQ^)&e$4sZk352^gj!mkdD{v?8Ddk(Fowf)ZUU1xqvwA|*Y<7l9O!+IBke`A{s( z3NclXRE6Ub;RqX!Mv)l|8w#;sOmpHxJ=-y9>t3 z5J9gD9a2%6RVPo4o3;U~-f6!~+fl2)H7^4r=|YQa=27svh|E`!A|ev|yuH0>+giT-wH1n^;Jh=7eJ$HgOZbo9py zJYI7tHI}b^-T3tS&>VY2U0&X|5r0}g`{AaVd$o8t)+IJphS?Lw8h!Wrjiqn(gYfOO zE61PoJ^TLU{rp1a(i*t;r*KkS%=Ap2xwE1)C${-nuT0YKa&z~IH{%ahXZk1HU*J)r h@NsK!7qT_*xvP&@*u2e8Z2rFJ-=`88^R){QV?Y1^ literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/clock6_hand_second.png b/app/src/main/res/mipmap-mdpi/clock6_hand_second.png new file mode 100644 index 0000000000000000000000000000000000000000..beb73db2795dc32a9221824b6f6b21438d1c2d1b GIT binary patch literal 1079 zcmaJ=O>5LZ7*1&sDP29N2c<$t5f#jLvfISQvYYI-i*8%Ci(S36*<{iU+ho#Y+THe4 z3Ld=lAXV@x9t1(qTM?;H6g}!e#6$512&JM2Ma0Q|R1a(CGBfWy&-*^}e%zj#7)$h@ z=_d#xksmjTc<&>Kp24F>@ac2!sS&)LM%gl&h7PKmAt2H=tN=3ane(6sOnYVVEx@2& z-z}9KW)sB7Xd^JK8bD+P%)7ou?LFV7NY~b=8M(j}0v%M{@zoGa zuTGS#)taT))aVs*q@iL59zZ79@D}_?ZD>@}uZqvHnWe}k1l2UEC8}JQB6S!7Qf890 z#U)c@N?~|8m6B4INP**JmJ?Z#qXkiwI8_qJ_M&jK(00_Kk!#1oH;t+y6sRm)uh*Hn z$iQ%(rFt%%}jxAcESpl>ta|#WBq|g;da%c_=J62Mt0A*O|`02*a38_q0 z5jjyYGCZG6DZDNi$&4c8a#Ge1^$s`hN67Ro(24Eh*e$M*JCv*HAutgPOAsz}x?rjb z5sa!ZAa%W2b@IZD>)Ws%U5v}r`n3T(j|U@wF9$;ed^|ZJ9+8bVdnfRC z&E}1CsqyK{ho^}(ZoqhVb@SY_t@Pvkjju1>-`!bc9zT3= zkN$q=^5*c#$&H_Q+VPrm9_ia>muGjker@$TuU|Ed#P9X7wH{(eKQ_2q+ux6E`Rs)8 IBr~`E2h?X&I{*Lx literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/low_power_battery.png b/app/src/main/res/mipmap-mdpi/low_power_battery.png new file mode 100644 index 0000000000000000000000000000000000000000..1bcf5861f45267436d578af4cb5f8a56278bc1ce GIT binary patch literal 2013 zcmaJ?Yfuws7mi2~Q5+}~Ef>4Qs=#M%B;gVXB#;0B5@L+yB2+@MK*(j|W+A{J5G$zA zYPg6FsKqw$K@miX@EJr63RqeyHAvM0^+urcIf7%ws$jcNvHelHGrRA3-#O27o^#%3 zW)JdtVYW8THW&=XmJ`krpsN@9hFV*pU&Ax29CUdfVaFodp%g?Tf{om>r3(70(cWiR05GqAQN%kWEzD? zqj&>v9xPf7mZZ=Gtk5^L&>bC{h9D{$fuPZ7@ES56f>Q}3e}8`h(VO7yjYBhV>TD$< z%EBqt8x|Q@pjr$|RfrT)0`rWbWGDlnV^O7lwxCeGrB$lmj0qhWAxoqpknqI$mKGDa z+<#A1DBfnP5drv@-hU)k3$s-qK>(_u3|Nd_T*`*|QYu;q42lp47DAAGaf{Dt*h5<71Pg$k|A0%2(;C<%oj1+dUIO}exe z%94Ccc<#d2Rdupf7Pz7U|oGT zGV;?CHJRy={F{~O4x@YWpI6UFMz(g5)hRhuzm?^um`Apz=BXcRE>6j};R>H%8P&mF zfUTYJr)4+HjEi>fSx)W{)LD=A>P{NEZd9=oFA8U34jil<{O8scBheu5lAijfOl9|x5qI!Z-QOzFk& zA7z|N?`gXW?|&E*VZPqttEcLdJDmpH-Nv84(9`u{*j6h|Y;=5>7Z$hKt$e5BMa>E5 zWRGu#9)vFx4PdH`O*wm4ktqd^-|37~#uVq-Yp=>@$^+bmN_g|}ChOrVQ3sQ*en~K! z*}(61lG;hjAN_FMkIT%Z{lWX#PPvB-%kD%${pWXlLY;k@@Of*sUTPEXl<#A_J3UR> zS8OP)yj2lBZs+io7T3?`+uun4^vbzWeY2PAux>Bpk@rw?E&V@^A6lLIg8ksm`IBF^ zvaiIgNU`k7z%@5N?bA68a{i-X3(ZkJk+vx*f7cG(h7$E zm$nVZa7je!X>JVB5&THVszLZ2_bu3(U2_RC_qj)_YbMiv&R8}##0#z;d}rwAgvNaz zTym<7ef8@xZjr%M1mssCMM%))srwyk%Y0Oh#_~=JA5&k&4QGt7Io9IgP}EJ4#5o{^N$PHT`hd!tbIHl z(~^zJIj}0TRB351=oV?hJC3c)T(`Teq@}X`fj_0|q08n>;GyJ(_4n!5aygsAUe^YA z^&x8~Xq!vTy2>XVjXv^B56{w`tq ha$NyAu5r#j31d1sZk2v4fjR%f<*<3I=HR5ge*hf2G$sH5 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/low_power_dial.png b/app/src/main/res/mipmap-mdpi/low_power_dial.png new file mode 100644 index 0000000000000000000000000000000000000000..5029f40c72c7e2800e9e0029accae90f091f750c GIT binary patch literal 2467 zcmaJ@c|4T+9)8EzBOP43&KOH_m@#I?GG|6-%n)g8jU|LJiy6$)ER3y0>1Yv(L?K(r zn%p+Bl&#{RM4TdZ$}u{XhNM2~j!ruFkK27epZEPOpXYhL+w;ep>EpFkUDZGp004Cl zccPzc^^v_OWkuQ7SlB)-Tl9slLBbtehA^JOrvrEzHLqfZZbIQK&I=AtaI>#p2+guUp!o5Ecyw4MdY{Njw6b z$#PHR(|06#k*SF>R3{pAi!%f(#>fQNbRh*IX2)^_7%>j|MHeI6uU^BUkS`En3=aBt zQb8mi2!YF|L(njL8>+3n1H{1zhCn+wpd73rcD4vK+!hH(+S=G5F(_LM$`11Nfy$!s zX$*`X(d}z2*$D?_3WYoj93CGZ4~s{_xcn$M!pX@AZfgg(v$K&QYy=4$Aw_J%5tyzi z5a|LcpT!fhxE#o;A|;Y565^n;O#d!{&HE!J^nE9458Tpol# z_|i3qWgv?~Na0ZF9z+~erUGNJXc&T{gCmNFBqC90R|LY<0gpg9 z;T@1jJOV{T6I~qFxI`{h#HMqEYh2ntT-Wb%SM9*&$s!Z!d{!Kt=Emo;Az#YIu)d#* z%Xjs@a%tbsh45W2T$T)cb-4dE?6oVIgI2fStSdWwGe4apb39*W?dYSeT>zk{dd-kk-M{?;Z1Iicbv9L_ZhyJnxZqokHu&tPS!PkS5pl6_ zL8E#8JQ{(>d3!Lgs>iV#CHvm+|}>GJCVzta-DxYKzaicS}VnBMSLv9?uWFv|cfv z`sJn?cQR_Sb!vX{e&;^?6XuojSA@sid&1N1;KxmzUbv{2ejF+N)#z7E~q3wmM7A6*TC_6=?J-!{tJ-AZq zefNYs(=Fu)zsxG)-A;wM-_O-Hgn}?W1Lp(jSrcT0Bt(6##eSt4<$eg7Rdzvd`?%MBqi*LD2gZ);&l`{F z1eYe}sL1bHh{5avi7yMZ_Xw17anN2L@6z>spr9;FpJ5pFl=|p%J+p=zFV#B@&aLx` z20t|*dqM>fAZe3Mv3FB>pQbLhDYSgO#IrWL%JV}jlVXx(8kTA?5;hWA4}2obxNPTh9v>=Jrx0}5QW?ats!1px%2On(`%DX zMpdyk_g5Di#Lk_ohzc*gx@A82^pdsRrc2o4RX4pNrA}0|`V+;(>21x|twP?1FU^U9 zBP|)$hGn2+&uSgd*tbfHKnAjN19M=qShZ2!znUDQ5U^Y_tr7^JnB-K;qw-f>Z;v*~ zFHc20Gj9lxzOcywN_?Bl)B8PYmx4F6wUzEn^(Fz8nS0wO1y*Ae8N+>)wgm*qFi>=I=%*ruNf z_D&VV04=4SuBq4Lhw8B%fLhO+t`nQu8#@XP0qhGj$%#WNyxY3c!orY&V9R2Q=rFlI z{mLtEq+A3?zP&d%Q~AhJ_(R7}(aj6eRE@-*G(^MrivsZIh(X3J`8Tz}CG)>c&KHb5 ziX6SAv|eBZ!g>SV)enMKT;WIDD;Ox<0ESAn+#79BY+w!g4r=msCQfyB-KVM%tNJ^x zmo$?MT3fo*N*+=6)h#o2=MCnz4z}fu9;hxDsth-zoi!UN{-vr zygU(!OeQ-<1s^D^Kif2x)s7qDKWIp_;A@I}>vRw{8DpRIj{kP=lEVATBZ`WObH!>P z=Oc2*j_ABBX}zsH@UOV{7ao?4{)#;&Db`a=8cAk=K;Wntwoab?UKF*g|%2)I!C-Bc_*P~7RBrifK2cb0!i7F}i-HuDLn%3YD^}dC zpPwbe`Y^vdGQO`)RoAE#egoP2-$`)YG|0n#liR!T2y7a~6?2!ZWFstFy?n<0L^~gM(^zyd9 zXel_YLG=&vGhmFwwIwKoVbZEIdZmy#nXlB*7g03nlQ*HDtgsI3U+Z0$IhkC(@v5`Z zv}vp;y8=9h)HjxftA93L4p*BdSlOSLFpRKNJ(mU%HR_5AoetjWnD6`CE~f?@PG}n( T4;VVP`rG8;>P4(~iAehoKr#an literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/qs_background.png b/app/src/main/res/mipmap-mdpi/qs_background.png new file mode 100644 index 0000000000000000000000000000000000000000..1bc9fbd016503f4a3ed776b31c631b51faf91688 GIT binary patch literal 9876 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 - - - - - - + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 5aa14fd..d3c6f5a 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -2,4 +2,7 @@ 48dp + + 26dp + 42dp \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c5d1592..83c99c5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,6 +15,7 @@ 短信 设置 + 低电量模式 所有人 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 8d80872..55e31e6 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -59,4 +59,12 @@ false @android:color/transparent + + diff --git a/app/version_code.properties b/app/version_code.properties index faba9c9..66ab9d7 100644 --- a/app/version_code.properties +++ b/app/version_code.properties @@ -1,2 +1,2 @@ -#Wed Mar 25 19:58:58 CST 2020 -VERSION_CODE=22 +#Sun Mar 29 18:27:02 CST 2020 +VERSION_CODE=24 -- 2.17.1