From 3e440de56258cbabc479aca8faae56c5025bf312 Mon Sep 17 00:00:00 2001 From: Fanhuitong <981964879@qq.com> Date: Mon, 29 May 2023 10:21:55 +0800 Subject: [PATCH] =?UTF-8?q?version:3.5=20fix:=20update:=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=80=80=E5=87=BA=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=97=B9=E9=92=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 32 +- app/keystore/G10PMTK11.jks | Bin 0 -> 2352 bytes app/src/main/AndroidManifest.xml | 24 +- .../uiuios/aios/activity/ControlActivity.java | 55 +- .../uiuios/aios/activity/NoticeActivity.java | 234 ++---- .../aios/activity/NoticeInfoActivity.java | 267 +++++++ .../activity/alarm/AlarmClockActivity.java | 130 +++- .../activity/alarm/AlarmClockAddActivity.java | 495 +++++++++++++ .../activity/alarm/AlarmClockContact.java | 2 +- .../alarm/AlarmClockEditActivity.java | 675 ++++++++++++++++++ .../activity/alarm/AlarmClockPresenter.java | 2 +- .../activity/contact/ContactPresenter.java | 4 +- .../activity/records/RecordsActivity.java | 33 +- .../aios/activity/wifi/WiFiContact.java | 18 + .../activity/wifi/WiFiManagerActivity.java | 147 ++++ .../aios/activity/wifi/WiFiPresenter.java | 127 ++++ .../aios/adapter/AvailableWiFiAdapter.java | 99 +++ .../aios/adapter/CallRecordAdapter.java | 28 +- .../uiuios/aios/adapter/GoodsListAdapter.java | 2 +- .../aios/adapter/NotificationAdapter.java | 15 +- .../uiuios/aios/adapter/SavedWiFiAdapter.java | 155 ++++ .../aios/{adapter => alarm}/AlarmAdapter.java | 103 ++- .../aios/{bean => alarm}/AlarmClockData.java | 51 +- .../uiuios/aios/alarm/AlarmOpenHelper.java | 33 +- .../com/uiuios/aios/alarm/AlarmUtils.java | 494 ++++++++----- .../com/uiuios/aios/base/BaseApplication.java | 2 + .../aios/base/BaseLifecycleActivity.java | 116 +++ .../aios/base/BaseLightLifecycleActivity.java | 115 +++ .../com/uiuios/aios/bean/AlarmClockId.java | 16 + .../java/com/uiuios/aios/bean/WiFiInfo.java | 62 ++ .../uiuios/aios/dialog/DeleWifiDialog.java | 246 +++++++ .../com/uiuios/aios/dialog/DeleteDialog.java | 251 +++++++ .../com/uiuios/aios/dialog/WifiDialog.java | 265 +++++++ .../uiuios/aios/fragment/AppListFragment.java | 35 +- .../aios/fragment/custom/CustomFragment.java | 47 +- .../java/com/uiuios/aios/gson/GsonUtils.java | 144 ++++ .../aios/gson/IntegerDefault0Adapter.java | 35 + .../gson/NullStringToEmptyAdapterFactory.java | 45 ++ .../uiuios/aios/manager/AppStatusManager.java | 2 +- .../aios/network/NetInterfaceManager.java | 140 ++-- .../aios/network/api/AlarmClockAddApi.java | 23 + .../aios/network/api/AlarmClockApi.java | 2 +- .../aios/network/api/AlarmClockDeleteApi.java | 18 + .../aios/network/api/AlarmClockEditApi.java | 22 + .../aios/network/api/AlarmClockQueryApi.java | 17 + .../aios/service/main/MainSContact.java | 6 +- .../aios/service/main/MainSPresenter.java | 219 +++++- .../uiuios/aios/service/main/MainService.java | 30 +- .../java/com/uiuios/aios/utils/ApkUtils.java | 11 +- .../java/com/uiuios/aios/utils/FileUtil.java | 5 + .../com/uiuios/aios/utils/GlideLoadUtils.java | 18 + .../java/com/uiuios/aios/utils/GsonUtils.java | 24 - .../com/uiuios/aios/utils/ScreenUtil.java | 21 + .../java/com/uiuios/aios/utils/TimeUtils.java | 8 + .../java/com/uiuios/aios/utils/ToastUtil.java | 5 +- .../java/com/uiuios/aios/utils/WiFiUtils.java | 225 ++++++ app/src/main/res/drawable-hdpi/alarm_add.png | Bin 0 -> 4594 bytes app/src/main/res/drawable-hdpi/icon_add.png | Bin 0 -> 2455 bytes app/src/main/res/drawable-hdpi/icon_back.png | Bin 0 -> 843 bytes app/src/main/res/drawable-hdpi/icon_close.png | Bin 0 -> 1701 bytes .../main/res/drawable-hdpi/icon_incoming.png | Bin 0 -> 2099 bytes .../main/res/drawable-hdpi/icon_missed.png | Bin 0 -> 1795 bytes .../main/res/drawable-hdpi/icon_nodata.png | Bin 0 -> 13433 bytes .../main/res/drawable-hdpi/icon_outgoing.png | Bin 0 -> 2048 bytes .../res/drawable-hdpi/icon_passwd_hide.png | Bin 0 -> 1140 bytes .../res/drawable-hdpi/icon_passwd_show.png | Bin 0 -> 1107 bytes .../main/res/drawable-hdpi/icon_remove.png | Bin 0 -> 857 bytes .../res/drawable-hdpi/icon_wifi_available.png | Bin 0 -> 4421 bytes .../res/drawable-hdpi/icon_wifi_saved.png | Bin 0 -> 5649 bytes .../drawable-hdpi/icon_wifi_unavailable.png | Bin 0 -> 6005 bytes app/src/main/res/drawable-hdpi/settings1.png | Bin 0 -> 4205 bytes .../res/drawable/add_alarm_background.xml | 13 + .../drawable/add_alarm_cancel_background.xml | 13 + app/src/main/res/drawable/background_wifi.xml | 26 + .../res/drawable/background_wifi_white.xml | 26 + .../res/drawable/bt_activation_normnl.xml | 15 + .../res/drawable/bt_activation_pressed.xml | 15 + .../res/drawable/bt_activation_selector.xml | 13 + .../main/res/drawable/default_button_bg.xml | 13 + .../res/drawable/default_button_cancel_bg.xml | 13 + .../delete_wifi_cancel_background.xml | 12 + app/src/main/res/drawable/edit_background.xml | 18 + app/src/main/res/drawable/tv_times_bg.xml | 16 + .../main/res/drawable/tv_times_bg_loop.xml | 16 + .../drawable/tv_times_bg_loop_selector.xml | 9 + .../main/res/drawable/tv_times_bg_offday.xml | 16 + .../drawable/tv_times_bg_offday_selector.xml | 9 + .../main/res/drawable/tv_times_bg_once.xml | 16 + .../drawable/tv_times_bg_once_selector.xml | 9 + .../main/res/drawable/tv_times_bg_work.xml | 16 + .../drawable/tv_times_bg_work_selector.xml | 9 + .../res/drawable/wifi_passwd_background.xml | 13 + .../main/res/layout-land/activity_control.xml | 53 +- .../main/res/layout-land/fragment_custom.xml | 58 +- .../res/layout-land/fragment_custom_back.xml | 421 ----------- .../main/res/layout-land/item_goods_list.xml | 2 +- .../main/res/layout-port/activity_control.xml | 69 +- .../main/res/layout-port/fragment_custom.xml | 20 +- .../main/res/layout-port/item_goods_list.xml | 2 +- .../res/layout/activity_add_alarm_clock.xml | 407 +++++++++++ .../main/res/layout/activity_alarm_clock.xml | 77 +- app/src/main/res/layout/activity_notice.xml | 161 +++-- .../main/res/layout/activity_notice_info.xml | 89 +++ .../main/res/layout/activity_wifi_manager.xml | 142 ++++ app/src/main/res/layout/dialog_custom.xml | 8 +- app/src/main/res/layout/dialog_daily_app.xml | 8 +- app/src/main/res/layout/dialog_delete.xml | 121 ++++ .../main/res/layout/dialog_delete_wifi.xml | 129 ++++ app/src/main/res/layout/dialog_password.xml | 11 +- app/src/main/res/layout/dialog_single.xml | 4 +- app/src/main/res/layout/dialog_wifi.xml | 137 ++++ app/src/main/res/layout/item_alarm_clock.xml | 205 +++--- app/src/main/res/layout/item_call_record.xml | 33 +- app/src/main/res/layout/item_goods.xml | 2 +- .../main/res/layout/item_wifi_available.xml | 59 ++ app/src/main/res/layout/item_wifi_info.xml | 82 +++ .../res/layout/pickerview_custom_time.xml | 54 ++ app/src/main/res/layout/window_menu.xml | 67 ++ app/src/main/res/raw/ni.mp3 | Bin 0 -> 48045 bytes app/src/main/res/values/colors.xml | 9 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 13 + build.gradle | 5 + niceimageview/build.gradle | 8 +- 124 files changed, 6897 insertions(+), 1266 deletions(-) create mode 100644 app/keystore/G10PMTK11.jks create mode 100644 app/src/main/java/com/uiuios/aios/activity/NoticeInfoActivity.java create mode 100644 app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockAddActivity.java create mode 100644 app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockEditActivity.java create mode 100644 app/src/main/java/com/uiuios/aios/activity/wifi/WiFiContact.java create mode 100644 app/src/main/java/com/uiuios/aios/activity/wifi/WiFiManagerActivity.java create mode 100644 app/src/main/java/com/uiuios/aios/activity/wifi/WiFiPresenter.java create mode 100644 app/src/main/java/com/uiuios/aios/adapter/AvailableWiFiAdapter.java create mode 100644 app/src/main/java/com/uiuios/aios/adapter/SavedWiFiAdapter.java rename app/src/main/java/com/uiuios/aios/{adapter => alarm}/AlarmAdapter.java (69%) rename app/src/main/java/com/uiuios/aios/{bean => alarm}/AlarmClockData.java (76%) create mode 100644 app/src/main/java/com/uiuios/aios/base/BaseLifecycleActivity.java create mode 100644 app/src/main/java/com/uiuios/aios/base/BaseLightLifecycleActivity.java create mode 100644 app/src/main/java/com/uiuios/aios/bean/AlarmClockId.java create mode 100644 app/src/main/java/com/uiuios/aios/bean/WiFiInfo.java create mode 100644 app/src/main/java/com/uiuios/aios/dialog/DeleWifiDialog.java create mode 100644 app/src/main/java/com/uiuios/aios/dialog/DeleteDialog.java create mode 100644 app/src/main/java/com/uiuios/aios/dialog/WifiDialog.java create mode 100644 app/src/main/java/com/uiuios/aios/gson/GsonUtils.java create mode 100644 app/src/main/java/com/uiuios/aios/gson/IntegerDefault0Adapter.java create mode 100644 app/src/main/java/com/uiuios/aios/gson/NullStringToEmptyAdapterFactory.java create mode 100644 app/src/main/java/com/uiuios/aios/network/api/AlarmClockAddApi.java create mode 100644 app/src/main/java/com/uiuios/aios/network/api/AlarmClockDeleteApi.java create mode 100644 app/src/main/java/com/uiuios/aios/network/api/AlarmClockEditApi.java create mode 100644 app/src/main/java/com/uiuios/aios/network/api/AlarmClockQueryApi.java delete mode 100644 app/src/main/java/com/uiuios/aios/utils/GsonUtils.java create mode 100644 app/src/main/java/com/uiuios/aios/utils/ScreenUtil.java create mode 100644 app/src/main/java/com/uiuios/aios/utils/WiFiUtils.java create mode 100644 app/src/main/res/drawable-hdpi/alarm_add.png create mode 100644 app/src/main/res/drawable-hdpi/icon_add.png create mode 100644 app/src/main/res/drawable-hdpi/icon_back.png create mode 100644 app/src/main/res/drawable-hdpi/icon_close.png create mode 100644 app/src/main/res/drawable-hdpi/icon_incoming.png create mode 100644 app/src/main/res/drawable-hdpi/icon_missed.png create mode 100644 app/src/main/res/drawable-hdpi/icon_nodata.png create mode 100644 app/src/main/res/drawable-hdpi/icon_outgoing.png create mode 100644 app/src/main/res/drawable-hdpi/icon_passwd_hide.png create mode 100644 app/src/main/res/drawable-hdpi/icon_passwd_show.png create mode 100644 app/src/main/res/drawable-hdpi/icon_remove.png create mode 100644 app/src/main/res/drawable-hdpi/icon_wifi_available.png create mode 100644 app/src/main/res/drawable-hdpi/icon_wifi_saved.png create mode 100644 app/src/main/res/drawable-hdpi/icon_wifi_unavailable.png create mode 100644 app/src/main/res/drawable-hdpi/settings1.png create mode 100644 app/src/main/res/drawable/add_alarm_background.xml create mode 100644 app/src/main/res/drawable/add_alarm_cancel_background.xml create mode 100644 app/src/main/res/drawable/background_wifi.xml create mode 100644 app/src/main/res/drawable/background_wifi_white.xml create mode 100644 app/src/main/res/drawable/bt_activation_normnl.xml create mode 100644 app/src/main/res/drawable/bt_activation_pressed.xml create mode 100644 app/src/main/res/drawable/bt_activation_selector.xml create mode 100644 app/src/main/res/drawable/default_button_bg.xml create mode 100644 app/src/main/res/drawable/default_button_cancel_bg.xml create mode 100644 app/src/main/res/drawable/delete_wifi_cancel_background.xml create mode 100644 app/src/main/res/drawable/edit_background.xml create mode 100644 app/src/main/res/drawable/tv_times_bg.xml create mode 100644 app/src/main/res/drawable/tv_times_bg_loop.xml create mode 100644 app/src/main/res/drawable/tv_times_bg_loop_selector.xml create mode 100644 app/src/main/res/drawable/tv_times_bg_offday.xml create mode 100644 app/src/main/res/drawable/tv_times_bg_offday_selector.xml create mode 100644 app/src/main/res/drawable/tv_times_bg_once.xml create mode 100644 app/src/main/res/drawable/tv_times_bg_once_selector.xml create mode 100644 app/src/main/res/drawable/tv_times_bg_work.xml create mode 100644 app/src/main/res/drawable/tv_times_bg_work_selector.xml create mode 100644 app/src/main/res/drawable/wifi_passwd_background.xml delete mode 100644 app/src/main/res/layout-land/fragment_custom_back.xml create mode 100644 app/src/main/res/layout/activity_add_alarm_clock.xml create mode 100644 app/src/main/res/layout/activity_notice_info.xml create mode 100644 app/src/main/res/layout/activity_wifi_manager.xml create mode 100644 app/src/main/res/layout/dialog_delete.xml create mode 100644 app/src/main/res/layout/dialog_delete_wifi.xml create mode 100644 app/src/main/res/layout/dialog_wifi.xml create mode 100644 app/src/main/res/layout/item_wifi_available.xml create mode 100644 app/src/main/res/layout/item_wifi_info.xml create mode 100644 app/src/main/res/layout/pickerview_custom_time.xml create mode 100644 app/src/main/res/layout/window_menu.xml create mode 100644 app/src/main/res/raw/ni.mp3 diff --git a/app/build.gradle b/app/build.gradle index 770f2ff..61a7eea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.uiuios.aios" minSdkVersion 24 targetSdkVersion 29 - versionCode 23 - versionName "3.2" + versionCode 26 + versionName "3.5" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -83,6 +83,15 @@ android { v1SigningEnabled true v2SigningEnabled true } + + G10P{ + storeFile file("keystore/G10PMTK11.jks") + storePassword "123456" + keyAlias "G10PMTK11" + keyPassword "123456" + v1SigningEnabled true + v2SigningEnabled true + } } buildTypes { @@ -98,6 +107,18 @@ android { signingConfig signingConfigs.MTK8183 } + G10PDebug.initWith(debug) + G10PDebug { + versionNameSuffix "-debug" + debuggable true + signingConfig signingConfigs.G10P + } + + G10PRelease.initWith(release) + G10PRelease { + signingConfig signingConfigs.G10P + } + zhanRuiRelease.initWith(release) zhanRuiRelease { signingConfig signingConfigs.zhanRui @@ -228,7 +249,12 @@ dependencies { implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-core:1.0.16' implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native:1.0.16' //图片选择 - implementation 'io.github.lucksiege:pictureselector:v3.10.8' + implementation 'io.github.lucksiege:pictureselector:v3.11.1' +// implementation 'io.github.lucksiege:pictureselector:v2.5.8' + //验证码输入 +// implementation 'com.jacktuotuo.customview:verificationcodeview:1.0.5' + implementation 'com.contrarywind:Android-PickerView:4.1.9' + implementation 'com.github.ForgetAll:LoadingDialog:v1.1.2' } preBuild { diff --git a/app/keystore/G10PMTK11.jks b/app/keystore/G10PMTK11.jks new file mode 100644 index 0000000000000000000000000000000000000000..324fa3165901bfe56095885d02ba319749535507 GIT binary patch literal 2352 zcmd5-`8(9@9-glm`&b5zC6jDnMBlN#BVHLYy;6rXV~vEYLzW_BnXyEx$r6dNrjab! zMd)CVb%>Xct&t^kS%!+2bDeXp_lNTboFDEV?)&~+&+}aObzh%nZ)I-<0)cQG0QeVp z-7(+|Qjj+WbD+fi;&7{kKsW)A4EqHNa`CBh0Wbi~fdBwb2#gH-S~F(3@F}s8{;XW) zLTD`{td8FG62HZK+{{y}7g2Y~vNQ|&YA6e8bg|68mugo%=f2$J$9Cf`j zd{k;~dkoHeVsoFi#=a||+0U)wcs&*SK3Dr9irKV1hbW*#wYVDcGVOJ5KBJ6M-$!Ad zO_fFZxMph9h@K}*1mf1C3@-jKvJhJ|fhD&?WR*R>_ZSF zH(8jyq5*Hdn$zb{;%4VZ)W7I;wTD)9&(Vq(u`ZhUh}q)NpwiP4sqA3IlI!A7fXwj? z9}7smyO*y#8GgcfwQ=4aro6+OQs{9O@%xkO6#Y za7H{-jcq3W*4E=}F72we#+RwwVohVNaM!=eBGzal{N2vrI(_?}$PR9#tz&JChV2CC zg+}X}>dPJty6vqB+=_Qw_20WP(pMChU$SAo{7;XaYfI1@W3gfj7H(HP9FWw!LY?uR z9uRZY*{d=tL-c2SY);;6hH^bzqkP;pH;XUWE5!HS9`(O%B;S%C#$4zn+6zlWoIJD8 z7>JcLE@G;Lx(!eDbm1#}C;y0$d1IVkmfevAE7Q(u*DI=3GMxS0>0*bp%yYT%8mWrQ zDj-2By^O^7Qo<1NO`g}mI9Fr~oqMfl_LmRZ!aelokt%<7YhyM#tG!+R>yAqY-F3TA ze^G2CI;6>Yigv?!fL^<7PrxlA>9qzgg;8QmX-05u+&{lzp`0w$t%aCf-O=ROAFLeK z5{O7)0*)44Th&-aLyU6vpDB`A1c;7GSICvI#88h6A(%wr(FcettS=@LukI6Dabo>G zRJD|kcgh#vs7jdx$MBc?d*uZvUU6KMd{JNRqolJg_hntT(2k7^4pgz`q)%*dKJ52V z_cNVdopG|PqIUa7r%5s^XkZj-^#blj;jVB|bB#nkNmp~Eq{jWmwpH@sjszf_HtO0S z76O6JgJkG5NapCIK{)^p4qnK>R)c-zKw%#!z{QJ>I~TVtaIhgcAz*YIh9BhRf)Zd{ zq8!E-F$hrTknq5HtUTO&?GAtu1mTAgH=Gma>}TYQ5dirQIUgK$$_gY>6DH3|9`d>d27aoffMkG=gA4$WOt2z=ZfGfkzr%7*?HS@u zMv58#IrJBVFs%pOlueSSGtNiVF)OLnB+OlbClTwG97 zwyjs7gc^}6yDGRm=Yw2JK{UTzf2Q4zcV7AHiFTcbD)kwHRCr0|?(Y6q5}IKMxW-20 zqdli)_!H|GJbO-d4)kHlPU4F8^b3nQh`37L*Dl=4fYwDP+X{wk+P>qfoTWxkv8yrY?Lc%9jcHxk<1}6lO^0E_rf50SJ(10bT@A2Sq>$!jLerJUbJ! zo1m15!eG_aBfzl8*vhSugGwCO@-PVy8TG#h4r_-Jg>iyV0NDR~<_E<+$Q*#2jYD8- zhALK{hbivod@&GO<53Xpq6+eSkQ;#Lto%|?|Ni8-AzqPpQCue9RvD+)mbL0h%Y ztkK7SJi6OpB&LzIx*;Kc1o&QA_Dy;h`zDbY9p0cu)l(WeTQDR`O%abD9@POuUFvi& z_Z;gxi@BX1nKGJ!bqS~IO6DOYYx^S9-CH$B&)H5;Gy* - + + + - + + oldData = AlarmUtils.getInstance().getOldData(); - alarmClockData = oldData.get(code); - if (alarmClockData == null) { + mId = intent.getIntExtra("id", -1); + + mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); + mWakeLock = mPowerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "WakeAndLock"); + mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); + mWakeLock.acquire(60 * 1000L); + long[] pattern = {1000, 5000, 1000, 5000}; + mVibrator.vibrate(pattern, 0); + WakeUpUtils.wakeUpAndUnlockScreen(this); + + mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume, AudioManager.FLAG_PLAY_SOUND); + + mMediaPlayer = MediaPlayer.create(this, R.raw.ni); + // 开始播放 + mMediaPlayer.start(); + + positive.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent noticeIntent = new Intent(NoticeActivity.this, NoticeInfoActivity.class); + noticeIntent.putExtra("id", mId); + startActivity(noticeIntent); + finish(); } - Log.e(TAG, "onCreate: " + alarmClockData); - jz_video.postDelayed(new Runnable() { - @Override - public void run() { - showData(alarmClockData); - } - },1234); - } - - } - - private void showData(AlarmClockData alarmClockData) { - Log.e(TAG, "showData: " ); - audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); - int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); - audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume, AudioManager.FLAG_PLAY_SOUND); - tv_title.setText(alarmClockData.getTitle()); - bt_ok.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - HashMap oldData = AlarmUtils.getInstance().getOldData(); - AlarmClockData alarm = oldData.get(code); - if (alarm != null) { - alarm.setFinished(true); - AlarmUtils.getInstance().updateAlarmFinished(alarm); - } - NetInterfaceManager.getInstance() - .getUpdateAlarmObservable(alarmClockData.getId()) - .subscribe(new Observer() { - @Override - public void onSubscribe(@NonNull Disposable d) { - Log.e("showData", "onSubscribe: "); - } - - @Override - public void onNext(@NonNull BaseResponse baseResponse) { - Log.e("showData", "onNext: " + baseResponse); - } - - @Override - public void onError(@NonNull Throwable e) { - Log.e("showData", "onError: " + e.getMessage()); - onComplete(); - } - - @Override - public void onComplete() { - Log.e("showData", "onComplete: "); - finish(); - } - }); - - } }); - String voiceUrl = alarmClockData.getVoice(); - String voicemd5 = alarmClockData.getVoice_md5(); - String filePath = alarmClockData.getFile(); - - if (!TextUtils.isEmpty(voiceUrl)) { - cl_voice.setVisibility(View.VISIBLE); - String fileName = Utils.getFileNamefromURL(voiceUrl); - File file = new File(Utils.getDownLoadPath(NoticeActivity.this) + fileName); - String fileMD5 = FileUtils.getFileMD5ToString(file); -// if (!md5.equals(fileMD5)) { -// // TODO: 2021/12/16 -// } else { - mediaPlayer = new MediaPlayer(); - try { - // 切歌之前先重置,释放掉之前的资源 - mediaPlayer.reset(); - FileInputStream fis = new FileInputStream(file); - mediaPlayer.setDataSource(fis.getFD()); - // 设置播放源 -// mediaPlayer.setDataSource(file.getAbsolutePath()); - // 开始播放前的准备工作,加载多媒体资源,获取相关信息 - mediaPlayer.prepare(); - // 开始播放 - mediaPlayer.start(); - } catch (IOException e) { - e.printStackTrace(); - Log.e(TAG, "showData: " + e.getMessage()); - } -// } - } else { - cl_voice.setVisibility(View.GONE); - } - if (!TextUtils.isEmpty(filePath)) { - cl_vp.setVisibility(View.VISIBLE); - String fileType = FileUtil.getFileType(filePath); - Log.e(TAG, "showData: " + fileType); - if (FileUtil.isPictureFile(fileType)) { - jz_video.setVisibility(View.GONE); - imageView.setVisibility(View.VISIBLE); - RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(this, 16F))); - Glide.with(NoticeActivity.this).load(filePath).apply(options).into(imageView); - } else if (FileUtil.isVideoFile(fileType)) { - jz_video.setVisibility(View.VISIBLE); - imageView.setVisibility(View.GONE); - String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); - String realPath = Utils.getDownLoadPath(NoticeActivity.this) + fileName; - File file = new File(realPath); - JZDataSource jzDataSource; - if (!file.exists()) { - jzDataSource = new JZDataSource(filePath, ""); - Log.e(TAG, "showData: not exists"); - } else { - Log.e(TAG, "showData: exists " + file); - URI uri = file.toURI(); - jzDataSource = new JZDataSource(uri.toString(), ""); - } - jzDataSource.looping = true; - jz_video.setUp(jzDataSource, Jzvd.SCREEN_NORMAL); - jz_video.startPreloading(); - jz_video.startVideoAfterPreloading(); - jz_video.startVideo(); - - } - } else { - cl_vp.setVisibility(View.GONE); - } - } + @Override protected void onDestroy() { - Log.e(TAG, "onDestroy: " ); super.onDestroy(); - if (mediaPlayer != null) { - if (mediaPlayer.isPlaying()) { - mediaPlayer.stop(); + if (mMediaPlayer != null) { + if (mMediaPlayer.isPlaying()) { + mMediaPlayer.stop(); } - mediaPlayer.release(); - mediaPlayer = null; + mMediaPlayer.release(); + mMediaPlayer = null; } } @Override public void onBackPressed() { - Log.e(TAG, "onDestroy: " ); if (Jzvd.backPress()) { return; } @@ -240,9 +92,7 @@ public class NoticeActivity extends AppCompatActivity { } @Override - protected void onStop() { - Log.e(TAG, "onDestroy: " ); - super.onStop(); - Jzvd.releaseAllVideos(); + protected void onPause() { + super.onPause(); } } diff --git a/app/src/main/java/com/uiuios/aios/activity/NoticeInfoActivity.java b/app/src/main/java/com/uiuios/aios/activity/NoticeInfoActivity.java new file mode 100644 index 0000000..0b0ffb3 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/activity/NoticeInfoActivity.java @@ -0,0 +1,267 @@ +package com.uiuios.aios.activity; + +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.os.Bundle; +import android.os.PowerManager; +import android.os.Vibrator; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.blankj.utilcode.util.FileUtils; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.uiuios.aios.R; +import com.uiuios.aios.alarm.AlarmClockData; +import com.uiuios.aios.alarm.AlarmUtils; +import com.uiuios.aios.bean.BaseResponse; +import com.uiuios.aios.network.NetInterfaceManager; +import com.uiuios.aios.utils.FileUtil; +import com.uiuios.aios.utils.ScreenUtils; +import com.uiuios.aios.utils.Utils; +import com.uiuios.aios.utils.WakeUpUtils; +import com.uiuios.aios.view.JzvdStdAssert; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URI; +import java.util.HashMap; + +import butterknife.BindView; +import butterknife.ButterKnife; +import cn.jzvd.JZDataSource; +import cn.jzvd.Jzvd; +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; + +public class NoticeInfoActivity extends AppCompatActivity { + private String TAG = NoticeInfoActivity.class.getSimpleName(); + + @BindView(R.id.tv_title) + TextView tv_title; + @BindView(R.id.bt_ok) + Button bt_ok; + @BindView(R.id.cl_voice) + ConstraintLayout cl_voice; + @BindView(R.id.cl_vp) + ConstraintLayout cl_vp; + @BindView(R.id.jz_video) + JzvdStdAssert jz_video; + @BindView(R.id.imageView) + ImageView imageView; + + private AlarmClockData mAlarmClockData; + private int mId; + private MediaPlayer mMediaPlayer; + private PowerManager mPowerManager; + private PowerManager.WakeLock mWakeLock; + private AudioManager mAudioManager; + + private Vibrator mVibrator; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_notice_info); + ButterKnife.bind(this); + Intent intent = getIntent(); + mId = intent.getIntExtra("id", -1); + + mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); + mWakeLock = mPowerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "WakeAndLock"); + mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); + + mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume, AudioManager.FLAG_PLAY_SOUND); + + mMediaPlayer = new MediaPlayer(); + + if (mId == -1) { + finish(); + } else { + mWakeLock.acquire(60 * 1000L); + long[] pattern = {1000, 5000, 1000, 5000}; + mVibrator.vibrate(pattern, 0); + WakeUpUtils.wakeUpAndUnlockScreen(this); + + HashMap oldData = AlarmUtils.getInstance().getOldDataMap(); + mAlarmClockData = oldData.get(mId); + if (mAlarmClockData == null) { + finish(); + } + Log.e(TAG, "onCreate: " + mAlarmClockData); + showPic(mAlarmClockData); + jz_video.postDelayed(new Runnable() { + @Override + public void run() { + showData(mAlarmClockData); + } + }, 123); + } + } + + private void showPic(AlarmClockData alarmClockData) { + tv_title.setText(alarmClockData.getTitle()); + bt_ok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + HashMap oldData = AlarmUtils.getInstance().getOldDataMap(); + AlarmClockData alarm = oldData.get(mId); + if (alarm != null) { + alarm.setFinished(true); + AlarmUtils.getInstance().updateAlarmFinished(alarm); + } + NetInterfaceManager.getInstance() + .getUpdateAlarmObservable(alarmClockData.getId()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("showData", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("showData", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("showData", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("showData", "onComplete: "); + finish(); + } + }); + + } + }); + String voiceUrl = alarmClockData.getVoice(); + String voicemd5 = alarmClockData.getVoice_md5(); + if (!TextUtils.isEmpty(voiceUrl)) { + cl_voice.setVisibility(View.VISIBLE); + String fileName = Utils.getFileNamefromURL(voiceUrl); + File file = new File(Utils.getDownLoadPath(NoticeInfoActivity.this) + fileName); + String fileMD5 = FileUtils.getFileMD5ToString(file); +// if (!md5.equals(fileMD5)) { +// // TODO: 2021/12/16 +// } else { + try { + // 切歌之前先重置,释放掉之前的资源 + mMediaPlayer.reset(); + FileInputStream fis = new FileInputStream(file); + mMediaPlayer.setDataSource(fis.getFD()); + // 设置播放源 +// mediaPlayer.setDataSource(file.getAbsolutePath()); + // 开始播放前的准备工作,加载多媒体资源,获取相关信息 + mMediaPlayer.prepare(); + // 开始播放 + mMediaPlayer.start(); + } catch (IOException e) { + e.printStackTrace(); + Log.e(TAG, "showData: " + e.getMessage()); + } +// } + } else { + cl_voice.setVisibility(View.GONE); + } + String filePath = alarmClockData.getFile(); + RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(this, 16F))); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + String realPath = Utils.getDownLoadPath(NoticeInfoActivity.this) + fileName; + File file = new File(realPath); + if (file.exists()){ + Glide.with(NoticeInfoActivity.this).load(file).apply(options).error(R.drawable.icon_nodata).into(imageView); + }else { + Glide.with(NoticeInfoActivity.this).load(filePath).apply(options).error(R.drawable.icon_nodata).into(imageView); + } + } + + + private void showData(AlarmClockData alarmClockData) { + String filePath = alarmClockData.getFile(); + if (!TextUtils.isEmpty(filePath)) { + cl_vp.setVisibility(View.VISIBLE); + String fileType = FileUtil.getFileType(filePath); + Log.e(TAG, "showData: " + fileType); + if (FileUtil.isPictureFile(fileType)) { + jz_video.setVisibility(View.GONE); + imageView.setVisibility(View.VISIBLE); + RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(this, 16F))); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + String realPath = Utils.getDownLoadPath(NoticeInfoActivity.this) + fileName; + File file = new File(realPath); + if (file.exists()){ + Glide.with(NoticeInfoActivity.this).load(file).apply(options).error(R.drawable.icon_nodata).into(imageView); + }else { + Glide.with(NoticeInfoActivity.this).load(filePath).apply(options).error(R.drawable.icon_nodata).into(imageView); + } + } else if (FileUtil.isVideoFile(fileType)) { + jz_video.setVisibility(View.VISIBLE); + imageView.setVisibility(View.GONE); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + String realPath = Utils.getDownLoadPath(NoticeInfoActivity.this) + fileName; + File file = new File(realPath); + JZDataSource jzDataSource; + if (!file.exists()) { + jzDataSource = new JZDataSource(filePath, ""); + Log.e(TAG, "showData: not exists"); + } else { + Log.e(TAG, "showData: exists " + file); + URI uri = file.toURI(); + jzDataSource = new JZDataSource(uri.toString(), ""); + } + jzDataSource.looping = true; + jz_video.setUp(jzDataSource, Jzvd.SCREEN_NORMAL); + jz_video.startPreloading(); + jz_video.startVideoAfterPreloading(); + jz_video.startVideo(); + } + } else { + cl_vp.setVisibility(View.GONE); + } + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (mMediaPlayer != null) { + if (mMediaPlayer.isPlaying()) { + mMediaPlayer.stop(); + } + mMediaPlayer.release(); + mMediaPlayer = null; + } + } + + @Override + public void onBackPressed() { + if (Jzvd.backPress()) { + return; + } + super.onBackPressed(); + } + + @Override + protected void onPause() { + super.onPause(); + Jzvd.releaseAllVideos(); + } +} diff --git a/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockActivity.java b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockActivity.java index a94005d..813fe6d 100644 --- a/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockActivity.java +++ b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockActivity.java @@ -8,31 +8,48 @@ import android.util.Log; import android.view.View; import android.widget.ImageView; +import androidx.annotation.NonNull; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.trello.rxlifecycle4.RxLifecycle; +import com.trello.rxlifecycle4.android.ActivityEvent; import com.uiuios.aios.R; -import com.uiuios.aios.adapter.AlarmAdapter; -import com.uiuios.aios.base.BaseActivity; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.alarm.AlarmAdapter; +import com.uiuios.aios.alarm.AlarmUtils; +import com.uiuios.aios.base.BaseLightLifecycleActivity; +import com.uiuios.aios.alarm.AlarmClockData; +import com.uiuios.aios.bean.BaseResponse; +import com.uiuios.aios.dialog.DeleteDialog; +import com.uiuios.aios.network.NetInterfaceManager; import com.uiuios.aios.push.PushManager; -import com.uiuios.aios.push.tpush.MessageReceiver; import com.uiuios.aios.utils.ToastUtil; +import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; import cn.jzvd.Jzvd; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; -public class AlarmClockActivity extends BaseActivity implements AlarmClockContact.ClockView { +public class AlarmClockActivity extends BaseLightLifecycleActivity implements AlarmClockContact.ClockView { private static final String TAG = AlarmClockActivity.class.getSimpleName(); - @BindView(R.id.rv_goods) + @BindView(R.id.recyclerView) RecyclerView recyclerView; @BindView(R.id.iv_back) ImageView iv_back; - + @BindView(R.id.swipeRefreshLayout) + SwipeRefreshLayout swipeRefreshLayout; + @BindView(R.id.fab) + FloatingActionButton fab; + @BindView(R.id.cl_nodata) + ConstraintLayout cl_nodata; private AlarmClockPresenter mPresenter; private AlarmAdapter mAlarmAdapter; @@ -44,12 +61,22 @@ public class AlarmClockActivity extends BaseActivity implements AlarmClockContac @Override public void initView() { + UltimateBarX.statusBarOnly(this) + .colorRes(R.color.default_blue) + .fitWindow(true) + .apply(); ButterKnife.bind(this); mPresenter = new AlarmClockPresenter(this); mPresenter.attachView(this); mPresenter.setLifecycle(lifecycleSubject); mAlarmAdapter = new AlarmAdapter(); + mAlarmAdapter.setOnLongClickListener(new AlarmAdapter.OnLongClickListener() { + @Override + public void onLongClick(AlarmClockData alarmClockData) { + showDialog(alarmClockData); + } + }); recyclerView.setLayoutManager(new LinearLayoutManager(AlarmClockActivity.this)); recyclerView.setAdapter(mAlarmAdapter); iv_back.setOnClickListener(new View.OnClickListener() { @@ -58,27 +85,106 @@ public class AlarmClockActivity extends BaseActivity implements AlarmClockContac finish(); } }); + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + mPresenter.getAlarmClock(); + } + }); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + startActivity(new Intent(AlarmClockActivity.this, AlarmClockAddActivity.class)); + } + }); + } + + private void showDialog(AlarmClockData alarmClockData) { + DeleteDialog dialog = new DeleteDialog(this); + dialog.setTitle("提醒") + .setMessage("是否要删除本次闹钟") + .setPositive("确定") + .setNegtive("取消") + .setOnClickBottomListener(new DeleteDialog.OnClickBottomListener() { + @Override + public void onPositiveClick() { + deleteAlarm(alarmClockData); + dialog.dismiss(); + } + + @Override + public void onNegtiveClick() { + dialog.dismiss(); + } + }); + dialog.show(); + } + + private void deleteAlarm(AlarmClockData alarmClockData) { + if (alarmClockData.isIs_local()) { + alarmClockData.setDeleted(true); + AlarmUtils.getInstance().deleteAlarmClock(alarmClockData); + } else { + NetInterfaceManager.getInstance().deleteAlarmClockObservable(alarmClockData.getId()) + .compose(RxLifecycle.bindUntilEvent(lifecycleSubject, ActivityEvent.DESTROY)) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("deleteAlarm", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("deleteAlarm", "onNext: " + baseResponse); + if (baseResponse.code == 200) { + AlarmUtils.getInstance().deleteAlarmClock(alarmClockData); + ToastUtil.show("删除成功"); + } else { + ToastUtil.show("删除失败:" + baseResponse.msg); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("deleteAlarm", "onError: " + e.getMessage()); + alarmClockData.setDeleted(true); + AlarmUtils.getInstance().updateAlarmClock(alarmClockData); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("deleteAlarm", "onComplete: "); + mPresenter.getAlarmClock(); + } + }); + } } @Override public void initData() { registerAlarmClockReceiver(); - mPresenter.getAlarmClock(); } @Override public void showAlarmClock(List alarmClockData) { mAlarmAdapter.setAlarmClockData(alarmClockData); + swipeRefreshLayout.setRefreshing(false); + cl_nodata.setVisibility(View.GONE); + recyclerView.setVisibility(View.VISIBLE); } @Override public void setAlarmClockEmpty() { mAlarmAdapter.setAlarmClockData(null); + swipeRefreshLayout.setRefreshing(false); + cl_nodata.setVisibility(View.VISIBLE); + recyclerView.setVisibility(View.GONE); } @Override public void onError() { - ToastUtil.show("服务器连接失败,检查网络连接"); + swipeRefreshLayout.setRefreshing(false); } @Override @@ -90,6 +196,12 @@ public class AlarmClockActivity extends BaseActivity implements AlarmClockContac } } + @Override + protected void onResume() { + super.onResume(); + mPresenter.getAlarmClock(); + } + private void registerAlarmClockReceiver() { if (null == mAlarmClockReceiver) { mAlarmClockReceiver = new AlarmClockReceiver(); diff --git a/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockAddActivity.java b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockAddActivity.java new file mode 100644 index 0000000..3d36d25 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockAddActivity.java @@ -0,0 +1,495 @@ +package com.uiuios.aios.activity.alarm; + +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.text.TextUtils; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.RadioButton; +import android.widget.TextView; + +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.bigkoo.pickerview.builder.TimePickerBuilder; +import com.bigkoo.pickerview.listener.CustomListener; +import com.bigkoo.pickerview.listener.OnTimeSelectListener; +import com.bigkoo.pickerview.view.TimePickerView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.luck.picture.lib.basic.PictureSelector; +import com.luck.picture.lib.config.SelectMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.luck.picture.lib.interfaces.OnResultCallbackListener; +import com.shehuan.niv.NiceImageView; +import com.trello.rxlifecycle4.RxLifecycle; +import com.trello.rxlifecycle4.android.ActivityEvent; +import com.uiuios.aios.alarm.AlarmClockData; +import com.uiuios.aios.alarm.AlarmUtils; +import com.uiuios.aios.base.GlideEngine; +import com.uiuios.aios.bean.AlarmClockId; +import com.uiuios.aios.bean.BaseResponse; +import com.uiuios.aios.network.NetInterfaceManager; +import com.uiuios.aios.utils.FFmpegUtils; +import com.uiuios.aios.utils.FileUtil; +import com.uiuios.aios.utils.ScreenUtil; +import com.uiuios.aios.utils.TimeUtils; +import com.uiuios.aios.utils.ToastUtil; +import com.uiuios.aios.utils.Utils; +import com.uiuios.aios.R; +import com.uiuios.aios.alarm.AlarmClockData; +import com.uiuios.aios.alarm.AlarmUtils; +import com.uiuios.aios.base.BaseLifecycleActivity; +import com.uiuios.aios.base.GlideEngine; +import com.uiuios.aios.bean.AlarmClockId; +import com.uiuios.aios.bean.BaseResponse; +import com.uiuios.aios.network.NetInterfaceManager; +import com.uiuios.aios.utils.FileUtil; +import com.uiuios.aios.utils.ToastUtil; +import com.uiuios.aios.utils.Utils; +import com.xiasuhuei321.loadingdialog.view.LoadingDialog; +import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; + +public class AlarmClockAddActivity extends BaseLifecycleActivity { + private static final String TAG = AlarmClockAddActivity.class.getSimpleName(); + + @BindView(R.id.cl_content) + ConstraintLayout cl_content; + @BindView(R.id.ll_type) + LinearLayout ll_type; + @BindView(R.id.cl_type) + ConstraintLayout cl_type; + @BindView(R.id.tv_type) + TextView tv_type; + @BindView(R.id.cl_pic) + ConstraintLayout cl_pic; + @BindView(R.id.et_activation) + EditText et_activation; + @BindView(R.id.nv_pic) + NiceImageView nv_pic; + @BindView(R.id.iv_back) + ImageView iv_back; + @BindView(R.id.bt_confirm) + Button bt_confirm; + @BindView(R.id.bt_cancel) + Button bt_cancel; + @BindView(R.id.tv_duration) + TextView tv_duration; + + @BindView(R.id.rb1) + RadioButton rb1; + @BindView(R.id.rb2) + RadioButton rb2; + @BindView(R.id.rb3) + RadioButton rb3; + @BindView(R.id.rb4) + RadioButton rb4; + + private PopupWindow mPopupWindow; + + private TimePickerView pvTime; + private String mPictrueFilePath; + private Date mDate; + /*类型 1一次性 2每天 3周一到周五 4周六周日*/ + private int mType = 1; + + @Override + public int getLayoutId() { + return R.layout.activity_add_alarm_clock; + } + + @Override + public void initView() { + lifecycleSubject.onNext(ActivityEvent.CREATE); + UltimateBarX.statusBarOnly(this) + .colorRes(R.color.default_blue) + .fitWindow(true) + .apply(); + + ButterKnife.bind(this); + initTimePicker(); + + + rb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + if (b) { + ColorStateList colorStateList = getResources().getColorStateList(R.color.white); + rb1.setTextColor(colorStateList); + mType = 1; + } else { + ColorStateList colorStateList = getResources().getColorStateList(R.color.radio_botton_gray); + rb1.setTextColor(colorStateList); + } + } + }); + rb2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + if (b) { + ColorStateList colorStateList = getResources().getColorStateList(R.color.white); + rb2.setTextColor(colorStateList); + mType = 2; + } else { + ColorStateList colorStateList = getResources().getColorStateList(R.color.radio_botton_gray); + rb2.setTextColor(colorStateList); + } + } + }); + rb3.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + if (b) { + ColorStateList colorStateList = getResources().getColorStateList(R.color.white); + rb3.setTextColor(colorStateList); + mType = 3; + } else { + ColorStateList colorStateList = getResources().getColorStateList(R.color.radio_botton_gray); + rb3.setTextColor(colorStateList); + } + } + }); + rb4.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + if (b) { + ColorStateList colorStateList = getResources().getColorStateList(R.color.white); + rb4.setTextColor(colorStateList); + mType = 4; + } else { + ColorStateList colorStateList = getResources().getColorStateList(R.color.radio_botton_gray); + rb4.setTextColor(colorStateList); + } + } + }); + + rb1.setChecked(true); + + cl_pic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + openSelector(); + } + }); + cl_type.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// showTimeFilterWindow(); + } + }); + nv_pic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + openSelector(); + } + }); + bt_confirm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + checkContent(); + } + }); + bt_cancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + finish(); + } + }); + iv_back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + finish(); + } + }); + } + + @Override + public void initData() { + + } + + private void showTimeFilterWindow() { + if (mPopupWindow == null) { + View view = getLayoutInflater().inflate(R.layout.window_menu, null); + TextView tvMenuOne = view.findViewById(R.id.tv_menuOne); + TextView tvMenuTwo = view.findViewById(R.id.tv_menuTwo); + TextView tvMenuThree = view.findViewById(R.id.tv_menuThree); + TextView tvMenuFour = view.findViewById(R.id.tv_menuFour); + mPopupWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); + mPopupWindow.setOutsideTouchable(true); + tvMenuOne.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mType = 1; + tv_type.setText("只响一次"); + mPopupWindow.dismiss(); + } + }); + tvMenuTwo.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mType = 2; + tv_type.setText("每天"); + mPopupWindow.dismiss(); + } + }); + tvMenuThree.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mType = 3; + tv_type.setText("周一至周五"); + mPopupWindow.dismiss(); + } + }); + tvMenuFour.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mType = 4; + tv_type.setText("周六至周日"); + mPopupWindow.dismiss(); + } + }); + } + if (mPopupWindow.isShowing()) { + mPopupWindow.dismiss(); + } else { + Log.e(TAG, "showTimeFilterWindow: right " + tv_type.getRight()); + Log.e(TAG, "showTimeFilterWindow: top " + tv_type.getTop()); + Log.e(TAG, "showTimeFilterWindow: right " + cl_type.getRight()); + Log.e(TAG, "showTimeFilterWindow: top " + cl_type.getTop()); + mPopupWindow.showAtLocation(cl_type, Gravity.END, 20, 0); + } + } + + LoadingDialog mLoadingDialog; + + private void checkContent() { + + pvTime.returnData(); + if (TextUtils.isEmpty(et_activation.getText())) { + ToastUtil.show("请输入标题"); + return; + } + if (TextUtils.isEmpty(mPictrueFilePath)) { + ToastUtil.show("请选择图片"); + return; + } + String timeStamp = getTime(mDate); + Log.e(TAG, "checkContent: " + timeStamp); + Log.e(TAG, "checkContent: " + mPictrueFilePath); +// Uri uri = Uri.parse(pictrueFilePath); +// File picFile = FileUtil.uriToFile(uri, AlarmClockAddActivity.this); + File picFile = new File(mPictrueFilePath); + MediaType mediaType = MediaType.Companion.parse("image/png"); + RequestBody requestBody = RequestBody.Companion.create(picFile, mediaType); + MultipartBody.Part body = MultipartBody.Part.createFormData("file", picFile.getName(), requestBody); + AlarmClockData alarmClockData = new AlarmClockData(); + alarmClockData.setFile(mPictrueFilePath); + alarmClockData.setType(mType); + alarmClockData.setTime(timeStamp); + alarmClockData.setTitle(et_activation.getText().toString()); + alarmClockData.setRemind_type(0); + alarmClockData.setIs_onoff(1); + + Map params = new HashMap<>(); + params.put("sn", Utils.getSerial()); + params.put("time", timeStamp); + params.put("type", String.valueOf(mType)); + params.put("title", et_activation.getText().toString()); + params.put("remind_type", "0"); + params.put("is_onoff", "1"); + + mLoadingDialog = new LoadingDialog(this); + mLoadingDialog.setLoadingText("正在上传") + .setSuccessText("添加成功") + .setFailedText("添加失败") + .setInterceptBack(true) + .setLoadSpeed(LoadingDialog.Speed.SPEED_ONE) + .closeSuccessAnim() + .show(); + + NetInterfaceManager.getInstance().getAlarmClockAddObservable(params, body) + .compose(RxLifecycle.bindUntilEvent(lifecycleSubject, ActivityEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("checkContent", "onSubscribe: "); + bt_confirm.setEnabled(false); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("checkContent", "onNext: " + baseResponse); + if (baseResponse.code == 200) { + ToastUtil.show("添加成功"); +// int id = baseResponse.data.getId(); +// alarmClockData.setId(id); +// AlarmUtils.getInstance().addAlarmClock(alarmClockData); + mLoadingDialog.loadSuccess(); + mLoadingDialog.close(); + finish(); + } else { + ToastUtil.show("添加失败:" + baseResponse.msg); + bt_confirm.setEnabled(true); + mLoadingDialog.loadFailed(); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("checkContent", "onError: " + e.getMessage()); + ToastUtil.show("已保存到本地"); + ToastUtil.show("添加成功"); + ThreadLocalRandom random = ThreadLocalRandom.current(); + int fakeId = random.nextInt(Integer.MAX_VALUE); + Log.e(TAG, "onError: fakeId = " + fakeId); + alarmClockData.setId(fakeId); + alarmClockData.setIs_local(true); + Log.e(TAG, "onError: addAlarmClock = " + AlarmUtils.getInstance().addAlarmClock(alarmClockData)); + + onComplete(); + finish(); + } + + @Override + public void onComplete() { + Log.e("checkContent", "onComplete: "); + mLoadingDialog.close(); + bt_confirm.setEnabled(true); + } + }); + } + + private void openSelector() { + PictureSelector.create(AlarmClockAddActivity.this) + .openGallery(SelectMimeType.ofAll()) + .setSelectionMode(1) + .setImageEngine(GlideEngine.createGlideEngine()) + .forResult(new OnResultCallbackListener() { + @Override + public void onResult(ArrayList result) { + mPictrueFilePath = result.get(0).getRealPath(); + File file = new File(mPictrueFilePath); + if (file.exists()) { + RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(AlarmClockAddActivity.this, 8F))); + Glide.with(nv_pic).load(file).apply(options).into(nv_pic); + nv_pic.setVisibility(View.VISIBLE); + cl_pic.setVisibility(View.GONE); + if (FileUtil.isVideoFile(mPictrueFilePath)) { + FFmpegUtils.getDurationInMilliseconds(mPictrueFilePath, new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("openSelector", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull Integer integer) { + Log.e("openSelector", "onNext: " + integer); + tv_duration.setText(TimeUtils.secToTime(integer)); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("openSelector", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("openSelector", "onComplete: "); + } + }); + } else { + tv_duration.setText(""); + } + } else { + mPictrueFilePath = ""; + nv_pic.setVisibility(View.GONE); + cl_pic.setVisibility(View.VISIBLE); + } + } + + @Override + public void onCancel() { + Log.e(TAG, "onCancel: "); + } + }); + } + + private void initTimePicker() { + //控制时间范围(如果不设置范围,则使用默认时间1900-2100年,此段代码可注释) + //因为系统Calendar的月份是从0-11的,所以如果是调用Calendar的set方法来设置时间,月份的范围也要是从0-11 + Calendar selectedDate = Calendar.getInstance(); + + Calendar startDate = Calendar.getInstance(); + startDate.set(2013, 0, 23); + + Calendar endDate = Calendar.getInstance(); + endDate.set(2019, 11, 28); + + //时间选择器 + pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() { + @Override + public void onTimeSelect(Date date, View v) {//选中事件回调 + // 这里回调过来的v,就是show()方法里面所添加的 View 参数,如果show的时候没有添加参数,v则为null + /*btn_Time.setText(getTime(date));*/ + mDate = date; + Log.e(TAG, "onTimeSelect: " + getTime(date)); + } + }) + .setLayoutRes(R.layout.pickerview_custom_time, new CustomListener() { + @Override + public void customLayout(View v) { + + } + }) + .setType(new boolean[]{false, false, false, true, true, false}) + .setLabel("", "", "", "时", "分", "") //设置空字符串以隐藏单位提示 hide label + .setDividerColor(Color.GRAY) + .setContentTextSize(30) + .setDate(selectedDate) + .setRangDate(startDate, selectedDate) + .setDecorView(cl_content)//非dialog模式下,设置ViewGroup, pickerView将会添加到这个ViewGroup中 + .setOutSideColor(0x00000000) + .setOutSideCancelable(false) + .build(); + pvTime.setKeyBackCancelable(false);//系统返回键监听屏蔽掉 + pvTime.show(cl_content, false);//弹出时间选择器,传递参数过去,回调的时候则可以绑定此view + + } + + private String getTime(Date date) { + SimpleDateFormat format; + if (mType == 1) { + format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + } else { + format = new SimpleDateFormat("HH:mm"); + } + return format.format(date); + } +} diff --git a/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockContact.java b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockContact.java index 08998f7..d4c911d 100644 --- a/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockContact.java +++ b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockContact.java @@ -2,7 +2,7 @@ package com.uiuios.aios.activity.alarm; import com.uiuios.aios.base.BasePresenter; import com.uiuios.aios.base.BaseView; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.alarm.AlarmClockData; import java.util.List; diff --git a/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockEditActivity.java b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockEditActivity.java new file mode 100644 index 0000000..ce35f5d --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockEditActivity.java @@ -0,0 +1,675 @@ +package com.uiuios.aios.activity.alarm; + +import android.content.Intent; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.RadioButton; +import android.widget.TextView; + +import androidx.annotation.CallSuper; +import androidx.annotation.CheckResult; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.bigkoo.pickerview.builder.TimePickerBuilder; +import com.bigkoo.pickerview.listener.CustomListener; +import com.bigkoo.pickerview.listener.OnTimeSelectListener; +import com.bigkoo.pickerview.view.TimePickerView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.luck.picture.lib.basic.PictureSelector; +import com.luck.picture.lib.config.SelectMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.luck.picture.lib.interfaces.OnResultCallbackListener; +import com.shehuan.niv.NiceImageView; +import com.trello.rxlifecycle4.LifecycleProvider; +import com.trello.rxlifecycle4.LifecycleTransformer; +import com.trello.rxlifecycle4.RxLifecycle; +import com.trello.rxlifecycle4.android.ActivityEvent; +import com.trello.rxlifecycle4.android.RxLifecycleAndroid; +import com.uiuios.aios.R; +import com.uiuios.aios.alarm.AlarmClockData; +import com.uiuios.aios.alarm.AlarmUtils; +import com.uiuios.aios.base.GlideEngine; +import com.uiuios.aios.bean.BaseResponse; +import com.uiuios.aios.network.NetInterfaceManager; +import com.uiuios.aios.utils.FFmpegUtils; +import com.uiuios.aios.utils.FileUtil; +import com.uiuios.aios.utils.GlideLoadUtils; +import com.uiuios.aios.utils.ScreenUtil; +import com.uiuios.aios.utils.TimeUtils; +import com.uiuios.aios.utils.ToastUtil; +import com.uiuios.aios.utils.Utils; +import com.xiasuhuei321.loadingdialog.view.LoadingDialog; +import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.subjects.BehaviorSubject; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; + +public class AlarmClockEditActivity extends AppCompatActivity implements LifecycleProvider { + + private static final String TAG = AlarmClockEditActivity.class.getSimpleName(); + private final BehaviorSubject lifecycleSubject = BehaviorSubject.create(); + + + @BindView(R.id.cl_content) + ConstraintLayout cl_content; + @BindView(R.id.ll_type) + LinearLayout ll_type; + @BindView(R.id.cl_type) + ConstraintLayout cl_type; + @BindView(R.id.tv_type) + TextView tv_type; + @BindView(R.id.cl_pic) + ConstraintLayout cl_pic; + @BindView(R.id.et_activation) + EditText et_activation; + @BindView(R.id.nv_pic) + NiceImageView nv_pic; + @BindView(R.id.iv_back) + ImageView iv_back; + @BindView(R.id.bt_confirm) + Button bt_confirm; + @BindView(R.id.bt_cancel) + Button bt_cancel; + @BindView(R.id.tv_title) + TextView tv_title; + @BindView(R.id.tv_duration) + TextView tv_duration; + + @BindView(R.id.rb1) + RadioButton rb1; + @BindView(R.id.rb2) + RadioButton rb2; + @BindView(R.id.rb3) + RadioButton rb3; + @BindView(R.id.rb4) + RadioButton rb4; + + private PopupWindow mMenuPopupWindow; + + private TimePickerView pvTime; + private String mPictrueFilePath; + + private Date mDate; + /*类型 1一次性 2每天 3周一到周五 4周六周日*/ + private int mType = 1; + private int mId; + private AlarmClockData mAlarmClockData; + + @Override + @androidx.annotation.NonNull + @CheckResult + public final Observable lifecycle() { + return lifecycleSubject.hide(); + } + + @Override + @androidx.annotation.NonNull + @CheckResult + public final LifecycleTransformer bindUntilEvent(@androidx.annotation.NonNull ActivityEvent event) { + return RxLifecycle.bindUntilEvent(lifecycleSubject, event); + } + + @Override + @androidx.annotation.NonNull + @CheckResult + public final LifecycleTransformer bindToLifecycle() { + return RxLifecycleAndroid.bindActivity(lifecycleSubject); + } + + @Override + @CallSuper + protected void onStart() { + super.onStart(); + lifecycleSubject.onNext(ActivityEvent.START); + } + + @Override + @CallSuper + protected void onResume() { + super.onResume(); + lifecycleSubject.onNext(ActivityEvent.RESUME); + } + + @Override + @CallSuper + protected void onPause() { + lifecycleSubject.onNext(ActivityEvent.PAUSE); + super.onPause(); + } + + @Override + @CallSuper + protected void onStop() { + lifecycleSubject.onNext(ActivityEvent.STOP); + super.onStop(); + } + + @Override + @CallSuper + protected void onDestroy() { + lifecycleSubject.onNext(ActivityEvent.DESTROY); + super.onDestroy(); + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_add_alarm_clock); + lifecycleSubject.onNext(ActivityEvent.CREATE); + UltimateBarX.statusBarOnly(this) + .colorRes(R.color.default_blue) + .fitWindow(true) + .apply(); + initView(); + initData(); + } + + private void initView() { + ButterKnife.bind(this); + tv_title.setText("编辑闹钟"); + initTimePicker(); + + cl_pic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + openSelector(); + } + }); + cl_type.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// showTimeFilterWindow(); + } + }); + nv_pic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + openSelector(); + } + }); + bt_confirm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + checkContent(); + } + }); + bt_cancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + finish(); + } + }); + iv_back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + finish(); + } + }); + rb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + if (b) { + ColorStateList colorStateList = getResources().getColorStateList(R.color.white); + rb1.setTextColor(colorStateList); + mType = 1; + } else { + ColorStateList colorStateList = getResources().getColorStateList(R.color.radio_botton_gray); + rb1.setTextColor(colorStateList); + } + } + }); + rb2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + if (b) { + ColorStateList colorStateList = getResources().getColorStateList(R.color.white); + rb2.setTextColor(colorStateList); + mType = 2; + } else { + ColorStateList colorStateList = getResources().getColorStateList(R.color.radio_botton_gray); + rb2.setTextColor(colorStateList); + } + } + }); + rb3.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + if (b) { + ColorStateList colorStateList = getResources().getColorStateList(R.color.white); + rb3.setTextColor(colorStateList); + mType = 3; + } else { + ColorStateList colorStateList = getResources().getColorStateList(R.color.radio_botton_gray); + rb3.setTextColor(colorStateList); + } + } + }); + rb4.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + if (b) { + ColorStateList colorStateList = getResources().getColorStateList(R.color.white); + rb4.setTextColor(colorStateList); + mType = 4; + } else { + ColorStateList colorStateList = getResources().getColorStateList(R.color.radio_botton_gray); + rb4.setTextColor(colorStateList); + } + } + }); + } + + private void initData() { + Intent intent = getIntent(); + if (intent == null) { + ToastUtil.show("获取闹钟信息失败"); + finish(); + return; + } + mId = intent.getIntExtra("id", -1); + if (mId == -1) { + ToastUtil.show("获取闹钟信息失败"); + finish(); + return; + } + NetInterfaceManager.getInstance().getAlarmClockByIdObservable(mId) + .compose(RxLifecycle.bindUntilEvent(lifecycleSubject, ActivityEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAlarmClockById", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse alarmClockDatabaseResponse) { + Log.e("getAlarmClockById", "onNext: " + alarmClockDatabaseResponse); + if (alarmClockDatabaseResponse.code == 200) { + AlarmClockData alarmClockData = alarmClockDatabaseResponse.data; + mAlarmClockData = alarmClockData; + setAlarmClockInfo(alarmClockData); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAlarmClockById", "onError: " + e.getMessage()); + HashMap oldData = AlarmUtils.getInstance().getOldDataMap(); + mAlarmClockData = oldData.get(mId); + setAlarmClockInfo(mAlarmClockData); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getAlarmClockById", "onComplete: "); + } + }); + } + + private void setAlarmClockInfo(AlarmClockData alarmClockData) { + if (alarmClockData == null) { + ToastUtil.show("闹钟信息为空"); + return; + } + Log.e(TAG, "setAlarmClockInfo: " + alarmClockData); + mType = alarmClockData.getType(); + switch (mType) { + default: + case AlarmUtils.ONCE: + rb1.setChecked(true); + tv_type.setText("只响一次"); + break; + case AlarmUtils.LOOP: + rb2.setChecked(true); + tv_type.setText("每天"); + break; + case AlarmUtils.WORKING_DAY: + rb3.setChecked(true); + tv_type.setText("周一至周五"); + break; + case AlarmUtils.OFF_DAY: + rb4.setChecked(true); + tv_type.setText("周六至周日"); + break; + } + String time = alarmClockData.getTime(); + Calendar date = getTime(time); + Calendar now = Calendar.getInstance(); + date.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1, now.get(Calendar.DAY_OF_MONTH)); + Log.e(TAG, "setAlarmClockInfo: " + date.getTimeInMillis()); + pvTime.setDate(date); + String title = alarmClockData.getTitle(); + et_activation.setText(title); + String fileUrl = alarmClockData.getFile(); + mPictrueFilePath = fileUrl; + String fileName = Utils.getFileNamefromURL(fileUrl); + File file = new File(Utils.getDownLoadPath(AlarmClockEditActivity.this) + fileName); + if (TextUtils.isEmpty(fileUrl)) { + cl_pic.setVisibility(View.VISIBLE); + nv_pic.setVisibility(View.GONE); + } else { + if (file.exists() && !file.isDirectory()) { + GlideLoadUtils.getInstance().glideLoad(this, file, nv_pic); + } else { + GlideLoadUtils.getInstance().glideLoad(this, fileUrl, nv_pic); + } + cl_pic.setVisibility(View.GONE); + nv_pic.setVisibility(View.VISIBLE); + } + } + + LoadingDialog mLoadingDialog; + + private void checkContent() { + pvTime.returnData(); + if (TextUtils.isEmpty(et_activation.getText())) { + ToastUtil.show("请输入标题"); + return; + } + if (TextUtils.isEmpty(mPictrueFilePath)) { + ToastUtil.show("请重新选择图片"); + return; + } + String timeStamp = getTime(mDate); + Log.e(TAG, "checkContent: " + timeStamp); + Log.e(TAG, "checkContent: " + mPictrueFilePath); +// Uri uri = Uri.parse(pictrueFilePath); +// File picFile = FileUtil.uriToFile(uri, AlarmClockAddActivity.this); + MultipartBody.Part body; + if (FileUtil.isLocalPath(mPictrueFilePath)) { + File picFile = new File(mPictrueFilePath); + MediaType mediaType = MediaType.Companion.parse("image/png"); + RequestBody requestBody = RequestBody.Companion.create(picFile, mediaType); + body = MultipartBody.Part.createFormData("file", picFile.getName(), requestBody); + } else { + String fileName = Utils.getFileNamefromURL(mPictrueFilePath); + File picFile = new File(Utils.getDownLoadPath(this) + fileName); + MediaType mediaType = MediaType.Companion.parse("image/png"); + RequestBody requestBody = RequestBody.Companion.create(picFile, mediaType); + body = MultipartBody.Part.createFormData("file", picFile.getName(), requestBody); + } + + mAlarmClockData.setId(mId); + mAlarmClockData.setType(mType); + mAlarmClockData.setTime(timeStamp); + mAlarmClockData.setTitle(et_activation.getText().toString()); + mAlarmClockData.setFile(mPictrueFilePath); + mAlarmClockData.setRemind_type(0); + mAlarmClockData.setIs_onoff(1); + mAlarmClockData.setFinished(false); + + + Map params = new HashMap<>(); + params.put("sn", Utils.getSerial()); + params.put("id", String.valueOf(mId)); + params.put("type", String.valueOf(mType)); + params.put("time", timeStamp); + params.put("title", et_activation.getText().toString()); + params.put("remind_type", "0"); + params.put("is_onoff", "1"); + + mLoadingDialog = new LoadingDialog(this); + mLoadingDialog.setLoadingText("正在上传") + .setSuccessText("编辑成功") + .setFailedText("编辑失败") + .setInterceptBack(true) + .setLoadSpeed(LoadingDialog.Speed.SPEED_ONE) + .closeSuccessAnim() + .show(); + + NetInterfaceManager.getInstance().getAlarmClockEditObservable(params, body) + .compose(RxLifecycle.bindUntilEvent(lifecycleSubject, ActivityEvent.DESTROY)) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("checkContent", "onSubscribe: "); + ToastUtil.show("正在上传"); + bt_confirm.setEnabled(false); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("checkContent", "onNext: " + baseResponse); + if (baseResponse.code == 200) { + ToastUtil.show("编辑成功"); + mLoadingDialog.loadSuccess(); + mLoadingDialog.close(); + mAlarmClockData.setEdited(false); + AlarmUtils.getInstance().updateAlarmClock(mAlarmClockData); + finish(); + } else { + ToastUtil.show("编辑失败:" + baseResponse.msg); + mLoadingDialog.loadFailed(); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("checkContent", "onError: " + e.getMessage()); + mAlarmClockData.setEdited(true); + AlarmUtils.getInstance().updateAlarmClock(mAlarmClockData); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("checkContent", "onComplete: "); + bt_confirm.setEnabled(true); + finish(); + mLoadingDialog.close(); + } + }); + } + + + private void showTimeFilterWindow() { + if (mMenuPopupWindow == null) { + View view = getLayoutInflater().inflate(R.layout.window_menu, null); + TextView tvMenuOne = view.findViewById(R.id.tv_menuOne); + TextView tvMenuTwo = view.findViewById(R.id.tv_menuTwo); + TextView tvMenuThree = view.findViewById(R.id.tv_menuThree); + TextView tvMenuFour = view.findViewById(R.id.tv_menuFour); + mMenuPopupWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); + mMenuPopupWindow.setOutsideTouchable(true); + tvMenuOne.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mType = 1; + tv_type.setText("只响一次"); + mMenuPopupWindow.dismiss(); + } + }); + tvMenuTwo.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mType = 2; + tv_type.setText("每天"); + mMenuPopupWindow.dismiss(); + } + }); + tvMenuThree.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mType = 3; + tv_type.setText("周一至周五"); + mMenuPopupWindow.dismiss(); + } + }); + tvMenuFour.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mType = 4; + tv_type.setText("周六至周日"); + mMenuPopupWindow.dismiss(); + } + }); + } + if (mMenuPopupWindow.isShowing()) { + mMenuPopupWindow.dismiss(); + } else { + Log.e(TAG, "showTimeFilterWindow: right " + tv_type.getRight()); + Log.e(TAG, "showTimeFilterWindow: top " + tv_type.getTop()); + Log.e(TAG, "showTimeFilterWindow: right " + cl_type.getRight()); + Log.e(TAG, "showTimeFilterWindow: top " + cl_type.getTop()); + mMenuPopupWindow.showAtLocation(cl_type, Gravity.END, 20, 0); + } + } + + private void openSelector() { + PictureSelector.create(AlarmClockEditActivity.this) + .openGallery(SelectMimeType.ofAll()) + .setSelectionMode(1) + .setImageEngine(GlideEngine.createGlideEngine()) + .forResult(new OnResultCallbackListener() { + @Override + public void onResult(ArrayList result) { + mPictrueFilePath = result.get(0).getRealPath(); + File file = new File(mPictrueFilePath); + if (file.exists()) { + RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtil.dip2px(AlarmClockEditActivity.this, 8F))); + Glide.with(nv_pic).load(file).apply(options).into(nv_pic); + nv_pic.setVisibility(View.VISIBLE); + cl_pic.setVisibility(View.GONE); + if (FileUtil.isVideoFile(mPictrueFilePath)) { + FFmpegUtils.getDurationInMilliseconds(mPictrueFilePath, new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("openSelector", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull Integer integer) { + Log.e("openSelector", "onNext: " + integer); + tv_duration.setText(TimeUtils.secToTime(integer)); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("openSelector", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("openSelector", "onComplete: "); + } + }); + } else { + tv_duration.setText(""); + } + } else { + mPictrueFilePath = ""; + nv_pic.setVisibility(View.GONE); + cl_pic.setVisibility(View.VISIBLE); + } + } + + @Override + public void onCancel() { + Log.e(TAG, "onCancel: "); + } + }); + } + + private void initTimePicker() { + //控制时间范围(如果不设置范围,则使用默认时间1900-2100年,此段代码可注释) + //因为系统Calendar的月份是从0-11的,所以如果是调用Calendar的set方法来设置时间,月份的范围也要是从0-11 + Calendar selectedDate = Calendar.getInstance(); + + Calendar startDate = Calendar.getInstance(); + startDate.set(2013, 0, 23); + + Calendar endDate = Calendar.getInstance(); + endDate.set(2019, 11, 28); + + //时间选择器 + pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() { + @Override + public void onTimeSelect(Date date, View v) {//选中事件回调 + // 这里回调过来的v,就是show()方法里面所添加的 View 参数,如果show的时候没有添加参数,v则为null + /*btn_Time.setText(getTime(date));*/ + mDate = date; + Log.e(TAG, "onTimeSelect: " + getTime(date)); + } + }) + .setLayoutRes(R.layout.pickerview_custom_time, new CustomListener() { + @Override + public void customLayout(View v) { + + } + }) + .setType(new boolean[]{false, false, false, true, true, false}) + .setLabel("", "", "", "时", "分", "") //设置空字符串以隐藏单位提示 hide label + .setDividerColor(Color.GRAY) + .setContentTextSize(30) + .setDate(selectedDate) + .setRangDate(startDate, selectedDate) + .setDecorView(cl_content)//非dialog模式下,设置ViewGroup, pickerView将会添加到这个ViewGroup中 + .setOutSideColor(0x00000000) + .setOutSideCancelable(false) + .build(); + pvTime.setKeyBackCancelable(false);//系统返回键监听屏蔽掉 + pvTime.show(cl_content, false);//弹出时间选择器,传递参数过去,回调的时候则可以绑定此view + + } + + private String getTime(Date date) { + SimpleDateFormat format; + if (mType == 1) { + format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + } else { + format = new SimpleDateFormat("HH:mm"); + } + return format.format(date); + } + + private Calendar getTime(String timeString) { + SimpleDateFormat sdf; + Calendar calendar = Calendar.getInstance(); + if (mType == 1) { + sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + } else { + sdf = new SimpleDateFormat("HH:mm"); + } + try { + Date date = sdf.parse(timeString); + calendar.setTime(date); + return calendar; + } catch (Exception e) { + Log.e(TAG, "getTime: " + e.getMessage()); + calendar.setTime(new Date()); + return calendar; + } + } +} diff --git a/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockPresenter.java b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockPresenter.java index 5c5f00d..453d9fd 100644 --- a/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockPresenter.java +++ b/app/src/main/java/com/uiuios/aios/activity/alarm/AlarmClockPresenter.java @@ -5,7 +5,7 @@ import android.content.Context; import androidx.annotation.NonNull; import com.trello.rxlifecycle4.android.ActivityEvent; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.alarm.AlarmClockData; import com.uiuios.aios.network.NetInterfaceManager; import java.util.List; diff --git a/app/src/main/java/com/uiuios/aios/activity/contact/ContactPresenter.java b/app/src/main/java/com/uiuios/aios/activity/contact/ContactPresenter.java index f6b948b..614aba3 100644 --- a/app/src/main/java/com/uiuios/aios/activity/contact/ContactPresenter.java +++ b/app/src/main/java/com/uiuios/aios/activity/contact/ContactPresenter.java @@ -11,9 +11,9 @@ import com.trello.rxlifecycle4.android.ActivityEvent; import com.uiuios.aios.bean.BaseResponse; import com.uiuios.aios.bean.Contact; import com.uiuios.aios.config.CommonConfig; +import com.uiuios.aios.gson.GsonUtils; import com.uiuios.aios.network.NetInterfaceManager; import com.uiuios.aios.network.UrlAddress; -import com.uiuios.aios.utils.GsonUtils; import java.lang.reflect.Type; import java.util.ArrayList; @@ -68,7 +68,7 @@ public class ContactPresenter implements ContactContact.Presenter { public void onNext(@NonNull BaseResponse> listBaseResponse) { Log.e("getContactList", "onNext: " + listBaseResponse); if (listBaseResponse.code == 200) { - mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJsonString(listBaseResponse.data)); + mMMKV.putString(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(listBaseResponse.data)); mView.setContact(listBaseResponse.data); } else { mMMKV.putString(UrlAddress.GET_MAIL_LIST, ""); diff --git a/app/src/main/java/com/uiuios/aios/activity/records/RecordsActivity.java b/app/src/main/java/com/uiuios/aios/activity/records/RecordsActivity.java index 6a8b888..e05c233 100644 --- a/app/src/main/java/com/uiuios/aios/activity/records/RecordsActivity.java +++ b/app/src/main/java/com/uiuios/aios/activity/records/RecordsActivity.java @@ -20,6 +20,7 @@ import com.uiuios.aios.R; import com.uiuios.aios.activity.dialer.DialerActivity; import com.uiuios.aios.adapter.CallRecordAdapter; import com.uiuios.aios.bean.RecordsInfo; +import com.uiuios.aios.dialog.DeleteDialog; import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX; import java.util.ArrayList; @@ -75,15 +76,37 @@ public class RecordsActivity extends AppCompatActivity { iv_clear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - for (RecordsInfo recordsInfo : dataList) { - String queryString = "NUMBER=" + recordsInfo.getNumber(); - getContentResolver().delete(CallLog.Calls.CONTENT_URI, queryString, null); - } - getData(); + showDialog(); } }); } + private void showDialog() { + DeleteDialog dialog = new DeleteDialog(this); + dialog.setTitle("提醒") + .setMessage("清空全部通话记录") + .setPositive("确定") + .setNegtive("取消") +// .setSingle(true) + .setOnClickBottomListener(new DeleteDialog.OnClickBottomListener() { + @Override + public void onPositiveClick() { + for (RecordsInfo recordsInfo : dataList) { + String queryString = "NUMBER=" + recordsInfo.getNumber(); + getContentResolver().delete(CallLog.Calls.CONTENT_URI, queryString, null); + } + getData(); + dialog.dismiss(); + } + + @Override + public void onNegtiveClick() { + dialog.dismiss(); + } + }); + dialog.show(); + } + @Override protected void onResume() { super.onResume(); diff --git a/app/src/main/java/com/uiuios/aios/activity/wifi/WiFiContact.java b/app/src/main/java/com/uiuios/aios/activity/wifi/WiFiContact.java new file mode 100644 index 0000000..80235df --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/activity/wifi/WiFiContact.java @@ -0,0 +1,18 @@ +package com.uiuios.aios.activity.wifi; + +import com.uiuios.aios.base.BasePresenter; +import com.uiuios.aios.base.BaseView; +import com.uiuios.aios.bean.WiFiInfo; + +import java.util.List; + +public class WiFiContact { + public interface Presenter extends BasePresenter { + void getWiFiList(); + } + + public interface WiFiView extends BaseView { + void setSavedWiFiList(List wiFiList); + void setAvailableWiFiList(List wiFiList); + } +} diff --git a/app/src/main/java/com/uiuios/aios/activity/wifi/WiFiManagerActivity.java b/app/src/main/java/com/uiuios/aios/activity/wifi/WiFiManagerActivity.java new file mode 100644 index 0000000..355d0ed --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/activity/wifi/WiFiManagerActivity.java @@ -0,0 +1,147 @@ +package com.uiuios.aios.activity.wifi; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.wifi.WifiManager; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.uiuios.aios.R; +import com.uiuios.aios.adapter.AvailableWiFiAdapter; +import com.uiuios.aios.adapter.SavedWiFiAdapter; +import com.uiuios.aios.base.BaseLightActivity; +import com.uiuios.aios.bean.WiFiInfo; +import com.uiuios.aios.utils.ToastUtil; +import com.uiuios.aios.view.HorizontalItemDecoration; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class WiFiManagerActivity extends BaseLightActivity implements WiFiContact.WiFiView { + + + @BindView(R.id.iv_close) + ImageView iv_close; + @BindView(R.id.rv_saved) + RecyclerView rv_saved; + @BindView(R.id.rv_available) + RecyclerView rv_available; + @BindView(R.id.tv_refresh) + TextView tv_refresh; + @BindView(R.id.tv_refresh2) + TextView tv_refresh2; + + private WiFiPresenter mPresenter; + private SavedWiFiAdapter mSavedWiFiAdapter; + private AvailableWiFiAdapter mAvailableWiFiAdapter; + + @Override + public int getLayoutId() { + return R.layout.activity_wifi_manager; + } + + @Override + public void initView() { + ButterKnife.bind(this); + mPresenter = new WiFiPresenter(this); + mPresenter.attachView(this); + mPresenter.setLifecycle(lifecycleSubject); + + iv_close.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + finish(); + } + }); + tv_refresh.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mPresenter.getWiFiList(); + } + }); + tv_refresh2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mPresenter.getWiFiList(); + } + }); + + mSavedWiFiAdapter = new SavedWiFiAdapter(); + mAvailableWiFiAdapter = new AvailableWiFiAdapter(); + + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); + linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); + rv_saved.setLayoutManager(linearLayoutManager); + rv_saved.addItemDecoration(new HorizontalItemDecoration(30, this)); + rv_saved.setAdapter(mSavedWiFiAdapter); + + LinearLayoutManager linearLayoutManager2 = new LinearLayoutManager(this); + linearLayoutManager2.setOrientation(LinearLayoutManager.VERTICAL); + rv_available.setLayoutManager(linearLayoutManager2); + rv_available.setAdapter(mAvailableWiFiAdapter); + + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); + filter.addAction("android.net.wifi.CONFIGURED_NETWORKS_CHANGE"); + filter.addAction("android.net.wifi.LINK_CONFIGURATION_CHANGED"); + filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); + registerReceiver(broadcastReceiver, filter); + + + mPresenter.getWiFiList(); + } + + @Override + public void initData() { + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(broadcastReceiver); + } + + private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action != null) { + switch (action) { + case ConnectivityManager.CONNECTIVITY_ACTION: + case WifiManager.SCAN_RESULTS_AVAILABLE_ACTION: + case "android.net.wifi.CONFIGURED_NETWORKS_CHANGE": + case "android.net.wifi.LINK_CONFIGURATION_CHANGED": + case WifiManager.NETWORK_STATE_CHANGED_ACTION: + case WifiManager.SUPPLICANT_STATE_CHANGED_ACTION: + default: + mPresenter.getWiFiList(); + break; + } + } + } + }; + + + @Override + public void setSavedWiFiList(List wiFiList) { + ToastUtil.show("刷新成功"); + mSavedWiFiAdapter.setResultList(wiFiList); + } + + @Override + public void setAvailableWiFiList(List wiFiList) { + mAvailableWiFiAdapter.setResultList(wiFiList); + } +} diff --git a/app/src/main/java/com/uiuios/aios/activity/wifi/WiFiPresenter.java b/app/src/main/java/com/uiuios/aios/activity/wifi/WiFiPresenter.java new file mode 100644 index 0000000..200da9b --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/activity/wifi/WiFiPresenter.java @@ -0,0 +1,127 @@ +package com.uiuios.aios.activity.wifi; + +import android.content.Context; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; + +import androidx.annotation.NonNull; + +import com.trello.rxlifecycle4.android.ActivityEvent; +import com.uiuios.aios.bean.WiFiInfo; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import io.reactivex.rxjava3.subjects.BehaviorSubject; + +import static android.text.TextUtils.isEmpty; + +public class WiFiPresenter implements WiFiContact.Presenter { + + private WiFiContact.WiFiView mView; + private Context mContext; + + private BehaviorSubject lifecycle; + + public void setLifecycle(BehaviorSubject lifecycle) { + this.lifecycle = lifecycle; + } + + public BehaviorSubject getLifecycle() { + return lifecycle; + } + + WiFiPresenter(Context context) { + this.mContext = context; + } + + @Override + public void attachView(@NonNull WiFiContact.WiFiView view) { + this.mView = view; + } + + @Override + public void detachView() { + this.mView = null; + } + + @Override + public void getWiFiList() { + WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + List wifiConfigurations = wifiManager.getConfiguredNetworks(); + Map savedWifiConfiguration = new HashMap<>(); + for (WifiConfiguration wifiConfiguration : wifiConfigurations) { + savedWifiConfiguration.put(wifiConfiguration.SSID.replaceAll("\"", ""), wifiConfiguration); + } + List scanResults = wifiManager.getScanResults(); + List filterList = scanResults.stream().filter(scanResult -> !isEmpty(scanResult.SSID)).collect(Collectors.toList()); + Map scanResultMap = new HashMap<>(); + List savedList = new ArrayList<>(); + List availableList = new ArrayList<>(); + + for (ScanResult scanResult : filterList) { + WiFiInfo wiFiInfo = new WiFiInfo(); + wiFiInfo.setSSID(scanResult.SSID); + wiFiInfo.setBSSID(scanResult.BSSID); + wiFiInfo.setLevel(scanResult.level); +// if (savedWifiConfiguration.get(scanResult.SSID) != null) { +// //跳过已保存的 +// continue; +// } + wiFiInfo.setAvailable(true); + wiFiInfo.setSaved(false); + scanResultMap.put(scanResult.SSID, wiFiInfo); + availableList.add(wiFiInfo); + } + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + for (Map.Entry wifiConfiguration : savedWifiConfiguration.entrySet()) { + WiFiInfo wiFiInfo = new WiFiInfo(); + if (wifiInfo != null) { + if (wifiConfiguration.getValue().SSID.equals(wifiInfo.getSSID())) { + wiFiInfo.setConnected(true); + } + } + String ssid = wifiConfiguration.getValue().SSID.replaceAll("\"", ""); + WiFiInfo wiFiInfo1 = scanResultMap.get(ssid); + if (wiFiInfo1 != null) { + + wiFiInfo.setSSID(wiFiInfo1.getSSID()); + wiFiInfo.setBSSID(wiFiInfo1.getBSSID()); + wiFiInfo.setLevel(wiFiInfo1.getLevel()); + wiFiInfo.setAvailable(true); + } else { + wiFiInfo.setSSID(wifiConfiguration.getValue().SSID.replaceAll("\"", "")); + wiFiInfo.setBSSID(wifiConfiguration.getValue().BSSID); + wiFiInfo.setAvailable(false); + } + wiFiInfo.setSaved(true); + savedList.add(wiFiInfo); + availableList.removeIf(new Predicate() { + @Override + public boolean test(WiFiInfo wiFiInfo) { + return wiFiInfo.getSSID().equals(ssid); + } + }); + } + mView.setSavedWiFiList(savedList.stream().sorted(new Comparator() { + @Override + public int compare(WiFiInfo o1, WiFiInfo o2) { + if (o1.isAvailable()) { + return -1; + } else if (o2.isAvailable()) { + return 1; + } else { + return 0; + } + } + }).collect(Collectors.toList())); + mView.setAvailableWiFiList(availableList); + } +} diff --git a/app/src/main/java/com/uiuios/aios/adapter/AvailableWiFiAdapter.java b/app/src/main/java/com/uiuios/aios/adapter/AvailableWiFiAdapter.java new file mode 100644 index 0000000..8cd0b3b --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/adapter/AvailableWiFiAdapter.java @@ -0,0 +1,99 @@ +package com.uiuios.aios.adapter; + +import android.content.Context; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.recyclerview.widget.RecyclerView; + +import com.uiuios.aios.R; +import com.uiuios.aios.bean.WiFiInfo; +import com.uiuios.aios.dialog.WifiDialog; +import com.uiuios.aios.utils.WiFiUtils; + +import java.util.List; + +public class AvailableWiFiAdapter extends RecyclerView.Adapter { + + private Context mContext; + private List mResultList; + + public void setResultList(List list) { + this.mResultList = list; + notifyDataSetChanged(); + } + + @NonNull + @Override + public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + mContext = parent.getContext(); + return new Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_wifi_available, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull Holder holder, int position) { + WiFiInfo wiFiInfo = mResultList.get(position); + holder.tv_name.setText(wiFiInfo.getSSID()); + if (wiFiInfo.isSaved()) { + if (wiFiInfo.isAvailable()) { + holder.iv_icon.setImageDrawable(mContext.getDrawable(R.drawable.icon_wifi_saved)); + } else { + holder.iv_icon.setImageDrawable(mContext.getDrawable(R.drawable.icon_wifi_unavailable)); + } + } else { + holder.iv_icon.setImageDrawable(mContext.getDrawable(R.drawable.icon_wifi_available)); + } + holder.root.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// if (wiFiInfo.isSaved()) { +// +// } else { + showPassword(wiFiInfo.getSSID()); +// } + } + }); + } + + private void showPassword(String ssid) { + WifiDialog passwordDialog = new WifiDialog(mContext); + passwordDialog.setTitle(String.format(mContext.getString(R.string.connect_wifi_ssid), ssid)); + passwordDialog.setOnClickBottomListener(new WifiDialog.OnClickBottomListener() { + @Override + public void onPositiveClick() { + WiFiUtils.addWiFiNetwork(ssid, passwordDialog.getPassword()); + passwordDialog.dismiss(); + } + }); + passwordDialog.show(); + passwordDialog.getWindow().setGravity(Gravity.CENTER); + passwordDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + passwordDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + + } + + @Override + public int getItemCount() { + return mResultList == null ? 0 : mResultList.size(); + } + + class Holder extends RecyclerView.ViewHolder { + ImageView iv_icon; + TextView tv_name; + ConstraintLayout root; + + public Holder(@NonNull View itemView) { + super(itemView); + iv_icon = itemView.findViewById(R.id.iv_icon); + tv_name = itemView.findViewById(R.id.tv_name); + root = itemView.findViewById(R.id.root); + } + } +} diff --git a/app/src/main/java/com/uiuios/aios/adapter/CallRecordAdapter.java b/app/src/main/java/com/uiuios/aios/adapter/CallRecordAdapter.java index 2618e0f..e4064b4 100644 --- a/app/src/main/java/com/uiuios/aios/adapter/CallRecordAdapter.java +++ b/app/src/main/java/com/uiuios/aios/adapter/CallRecordAdapter.java @@ -3,6 +3,7 @@ package com.uiuios.aios.adapter; import android.content.Context; import android.content.Intent; import android.net.Uri; +import android.provider.CallLog; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -24,7 +25,7 @@ public class CallRecordAdapter extends RecyclerView.Adapter mRecordsInfoList; - private SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("HH:mm"); + private SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("HH:mm:ss"); public void setRecordsInfoList(List recordsInfoList) { this.mRecordsInfoList = recordsInfoList; @@ -43,6 +44,18 @@ public class CallRecordAdapter extends RecyclerView.Adapter() { @Override - public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) { + public void onSubscribe(@NonNull Disposable d) { } @Override - public void onNext(@io.reactivex.rxjava3.annotations.NonNull Bitmap bitmap) { + public void onNext(@NonNull Bitmap bitmap) { Glide.with(holder.iv_cover).load(bitmap).into(holder.iv_cover); } @Override - public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) { + public void onError(@NonNull Throwable e) { } @@ -132,17 +131,17 @@ public class NotificationAdapter extends RecyclerView.Adapter() { @Override - public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) { + public void onSubscribe(@NonNull Disposable d) { } @Override - public void onNext(@io.reactivex.rxjava3.annotations.NonNull Integer integer) { + public void onNext(@NonNull Integer integer) { holder.tv_voice.setText(integer + "秒"); } @Override - public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) { + public void onError(@NonNull Throwable e) { } diff --git a/app/src/main/java/com/uiuios/aios/adapter/SavedWiFiAdapter.java b/app/src/main/java/com/uiuios/aios/adapter/SavedWiFiAdapter.java new file mode 100644 index 0000000..11cbea8 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/adapter/SavedWiFiAdapter.java @@ -0,0 +1,155 @@ +package com.uiuios.aios.adapter; + +import android.content.Context; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.recyclerview.widget.RecyclerView; + +import com.uiuios.aios.R; +import com.uiuios.aios.bean.WiFiInfo; +import com.uiuios.aios.dialog.DeleWifiDialog; +import com.uiuios.aios.dialog.WifiDialog; +import com.uiuios.aios.utils.WiFiUtils; + +import java.util.List; + +public class SavedWiFiAdapter extends RecyclerView.Adapter { + + private Context mContext; + private List mResultList; + + public void setResultList(List list) { + this.mResultList = list; + notifyDataSetChanged(); + } + + @NonNull + @Override + public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + mContext = parent.getContext(); + return new Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_wifi_info, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull Holder holder, int position) { + WiFiInfo wiFiInfo = mResultList.get(position); + holder.tv_name.setText(wiFiInfo.getSSID()); + if (wiFiInfo.isConnected()) { + holder.tv_connected.setVisibility(View.VISIBLE); + } else { + holder.tv_connected.setVisibility(View.GONE); + } + if (wiFiInfo.isSaved()) { + if (wiFiInfo.isAvailable()) { + holder.iv_icon.setImageDrawable(mContext.getDrawable(R.drawable.icon_wifi_saved)); + holder.tv_level.setText("信号:" + getWifiLevelText(wiFiInfo.getLevel()) + "(" + wiFiInfo.getLevel() + "dBm)"); + holder.tv_level.setVisibility(View.VISIBLE); + } else { + holder.iv_icon.setImageDrawable(mContext.getDrawable(R.drawable.icon_wifi_unavailable)); + holder.tv_level.setVisibility(View.GONE); + } + } else { + holder.iv_icon.setImageDrawable(mContext.getDrawable(R.drawable.icon_wifi_available)); + holder.tv_level.setText("信号:" + getWifiLevelText(wiFiInfo.getLevel()) + "(" + wiFiInfo.getLevel() + "dBm)"); + holder.tv_level.setVisibility(View.VISIBLE); + } + holder.root.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// if (wiFiInfo.isSaved()) { +// +// } else { + showPassword(wiFiInfo.getSSID()); +// } + } + }); + holder.root.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + showRemoveDialog(wiFiInfo.getSSID(), position); + return false; + } + }); + } + + private void showRemoveDialog(String ssid, int position) { + DeleWifiDialog deleWifiDialog = new DeleWifiDialog(mContext); + deleWifiDialog.setTitle("提醒"); + deleWifiDialog.setMessage(ssid); + deleWifiDialog.setOnClickBottomListener(new DeleWifiDialog.OnClickBottomListener() { + @Override + public void onPositiveClick() { + WiFiUtils.removeWiFiNetwork(ssid); + deleWifiDialog.dismiss(); + mResultList.remove(position); + notifyDataSetChanged(); + } + }); + deleWifiDialog.show(); + deleWifiDialog.getWindow().setGravity(Gravity.CENTER); + deleWifiDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + deleWifiDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + } + + private static final int MIN_RSSI = -100; + + private static final int MAX_RSSI = -55; + + private String getWifiLevelText(int db) { + if (db < MIN_RSSI) { + return "微弱"; + } else if (db < -88) { + return "一般"; + } else if (db < -77) { + return "良好"; + } else if (db < MAX_RSSI) { + return "极佳"; + } + return "一般"; + } + + private void showPassword(String ssid) { + WifiDialog passwordDialog = new WifiDialog(mContext); + passwordDialog.setTitle(String.format(mContext.getString(R.string.connect_wifi_ssid), ssid)); + passwordDialog.setOnClickBottomListener(new WifiDialog.OnClickBottomListener() { + @Override + public void onPositiveClick() { + WiFiUtils.addWiFiNetwork(ssid, passwordDialog.getPassword()); + passwordDialog.dismiss(); + } + }); + passwordDialog.show(); + passwordDialog.getWindow().setGravity(Gravity.CENTER); + passwordDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + passwordDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + + } + + @Override + public int getItemCount() { + return mResultList == null ? 0 : mResultList.size(); + } + + class Holder extends RecyclerView.ViewHolder { + ImageView iv_icon; + TextView tv_name, tv_level, tv_connected; + ConstraintLayout root; + + public Holder(@NonNull View itemView) { + super(itemView); + iv_icon = itemView.findViewById(R.id.iv_icon); + tv_name = itemView.findViewById(R.id.tv_name); + tv_level = itemView.findViewById(R.id.tv_level); + tv_connected = itemView.findViewById(R.id.tv_connected); + root = itemView.findViewById(R.id.root); + } + } +} diff --git a/app/src/main/java/com/uiuios/aios/adapter/AlarmAdapter.java b/app/src/main/java/com/uiuios/aios/alarm/AlarmAdapter.java similarity index 69% rename from app/src/main/java/com/uiuios/aios/adapter/AlarmAdapter.java rename to app/src/main/java/com/uiuios/aios/alarm/AlarmAdapter.java index b510fa7..a7bbc89 100644 --- a/app/src/main/java/com/uiuios/aios/adapter/AlarmAdapter.java +++ b/app/src/main/java/com/uiuios/aios/alarm/AlarmAdapter.java @@ -1,5 +1,6 @@ -package com.uiuios.aios.adapter; +package com.uiuios.aios.alarm; +import android.content.Intent; import android.graphics.Bitmap; import android.media.AudioAttributes; import android.media.MediaPlayer; @@ -9,7 +10,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; -import android.widget.Switch; import android.widget.TextView; import androidx.annotation.NonNull; @@ -21,7 +21,7 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; import com.uiuios.aios.R; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.activity.alarm.AlarmClockEditActivity; import com.uiuios.aios.utils.FFmpegUtils; import com.uiuios.aios.utils.ScreenUtils; import com.uiuios.aios.utils.Utils; @@ -42,12 +42,21 @@ public class AlarmAdapter extends RecyclerView.Adapter { private FragmentActivity mContext; private List mAlarmClockData; + private OnLongClickListener mOnLongClickListener; public void setAlarmClockData(List alarmClockData) { this.mAlarmClockData = alarmClockData; notifyDataSetChanged(); } + public void setOnLongClickListener(OnLongClickListener onLongClickListener) { + this.mOnLongClickListener = onLongClickListener; + } + + public interface OnLongClickListener { + void onLongClick(AlarmClockData alarmClockData); + } + @NonNull @Override public holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @@ -59,7 +68,7 @@ public class AlarmAdapter extends RecyclerView.Adapter { public void onBindViewHolder(@NonNull holder holder, int position) { AlarmClockData alarmClockData = mAlarmClockData.get(position); switch (alarmClockData.getType()) { - case 1: + case AlarmUtils.ONCE: try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); Date date = sdf.parse(alarmClockData.getTime()); @@ -69,19 +78,23 @@ public class AlarmAdapter extends RecyclerView.Adapter { } catch (ParseException e) { e.printStackTrace(); } - holder.tv_remind_type.setText("单次"); + holder.tv_remind_type.setText("一次"); + holder.tv_remind_type.setBackgroundResource(R.drawable.tv_times_bg_once); break; - case 2: + case AlarmUtils.LOOP: holder.tv_time.setText(alarmClockData.getTime()); - holder.tv_remind_type.setText("循环"); + holder.tv_remind_type.setText("每天"); + holder.tv_remind_type.setBackgroundResource(R.drawable.tv_times_bg_loop); break; - case 3: + case AlarmUtils.WORKING_DAY: holder.tv_time.setText(alarmClockData.getTime()); holder.tv_remind_type.setText("周一至周五"); + holder.tv_remind_type.setBackgroundResource(R.drawable.tv_times_bg_work); break; - case 4: + case AlarmUtils.OFF_DAY: holder.tv_time.setText(alarmClockData.getTime()); holder.tv_remind_type.setText("周六至周日"); + holder.tv_remind_type.setBackgroundResource(R.drawable.tv_times_bg_offday); break; default: } @@ -115,17 +128,17 @@ public class AlarmAdapter extends RecyclerView.Adapter { mMediaPlayer.prepareAsync(); FFmpegUtils.getDurationInMilliseconds(voice, new Observer() { @Override - public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) { + public void onSubscribe(@NonNull Disposable d) { } @Override - public void onNext(@io.reactivex.rxjava3.annotations.NonNull Integer integer) { + public void onNext(@NonNull Integer integer) { holder.tv_voice.setText(integer + "秒"); } @Override - public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) { + public void onError(@NonNull Throwable e) { } @@ -141,48 +154,49 @@ public class AlarmAdapter extends RecyclerView.Adapter { } }); } - String url = alarmClockData.getFile(); - String fileName = url.substring(url.lastIndexOf("/") + 1, url.length()); - String realPath = Utils.getDownLoadPath(mContext) + fileName; - File file = new File(realPath); - if (file.exists()) { - holder.iv_finish.setVisibility(View.VISIBLE); - }else { - holder.iv_finish.setVisibility(View.GONE); - } - if (TextUtils.isEmpty(url)) { + String fileUrl = alarmClockData.getFile(); + if (TextUtils.isEmpty(fileUrl)) { holder.cl_vp.setVisibility(View.GONE); } else { holder.cl_vp.setVisibility(View.VISIBLE); - if (isImgUrl(url)) { - holder.iv_cover.setVisibility(View.VISIBLE); + if (isImgUrl(fileUrl)) { + holder.imageView.setVisibility(View.VISIBLE); holder.jz_video.setVisibility(View.GONE); if (!mContext.isDestroyed()) { RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(mContext, 16F))); - Glide.with(mContext).load(url).apply(options).into(holder.iv_cover); + Glide.with(mContext).load(fileUrl).apply(options).into(holder.imageView); } } else { - holder.iv_cover.setVisibility(View.GONE); + holder.imageView.setVisibility(View.GONE); holder.jz_video.setVisibility(View.VISIBLE); - holder.jz_video.setUp(url, ""); + String fileName = Utils.getFileNamefromURL(fileUrl); + File file = new File(Utils.getDownLoadPath(mContext) + fileName); + String path; + if (file.exists() && !file.isDirectory()) { + path = file.getAbsolutePath(); + } else { + path = fileUrl; + } + holder.jz_video.setUp(path, ""); holder.jz_video.startButton.setImageDrawable(mContext.getDrawable(R.drawable.play)); - FFmpegUtils.loadVideoScreenshot(url, new Observer() { + FFmpegUtils.loadVideoScreenshot(path, new Observer() { @Override - public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) { + public void onSubscribe(@NonNull Disposable d) { } @Override - public void onNext(@io.reactivex.rxjava3.annotations.NonNull Bitmap bitmap) { + public void onNext(@NonNull Bitmap bitmap) { if (!mContext.isDestroyed()) { RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(mContext, 16F))); Glide.with(mContext).load(bitmap).apply(options).into(holder.jz_video.posterImageView); +// Glide.with(mContext).load(bitmap).into(holder.imageView); } holder.jz_video.startButton.setImageDrawable(mContext.getDrawable(R.drawable.play)); } @Override - public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) { + public void onError(@NonNull Throwable e) { } @@ -194,7 +208,21 @@ public class AlarmAdapter extends RecyclerView.Adapter { } } - + holder.root.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + mOnLongClickListener.onLongClick(alarmClockData); + return false; + } + }); + holder.root.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(mContext, AlarmClockEditActivity.class); + intent.putExtra("id", alarmClockData.getId()); + mContext.startActivity(intent); + } + }); } @@ -214,10 +242,9 @@ public class AlarmAdapter extends RecyclerView.Adapter { class holder extends RecyclerView.ViewHolder { TextView tv_time, tv_remind_type, tv_title, tv_voice; - ConstraintLayout cl_voice, cl_vp; + ConstraintLayout cl_voice, cl_vp, root; JzvdStdRound jz_video; - ImageView iv_cover, iv_finish; - Switch switch1; + ImageView imageView; public holder(@NonNull View itemView) { super(itemView); @@ -226,11 +253,11 @@ public class AlarmAdapter extends RecyclerView.Adapter { tv_title = itemView.findViewById(R.id.tv_title); tv_voice = itemView.findViewById(R.id.tv_voice); cl_voice = itemView.findViewById(R.id.cl_voice); - switch1 = itemView.findViewById(R.id.switch1); cl_vp = itemView.findViewById(R.id.cl_vp); + root = itemView.findViewById(R.id.root); jz_video = itemView.findViewById(R.id.jz_video); - iv_cover = itemView.findViewById(R.id.iv_cover); - iv_finish = itemView.findViewById(R.id.iv_finish); + imageView = itemView.findViewById(R.id.imageView); } } } + diff --git a/app/src/main/java/com/uiuios/aios/bean/AlarmClockData.java b/app/src/main/java/com/uiuios/aios/alarm/AlarmClockData.java similarity index 76% rename from app/src/main/java/com/uiuios/aios/bean/AlarmClockData.java rename to app/src/main/java/com/uiuios/aios/alarm/AlarmClockData.java index cb503af..de26715 100644 --- a/app/src/main/java/com/uiuios/aios/bean/AlarmClockData.java +++ b/app/src/main/java/com/uiuios/aios/alarm/AlarmClockData.java @@ -1,4 +1,4 @@ -package com.uiuios.aios.bean; +package com.uiuios.aios.alarm; import android.text.TextUtils; import android.util.Log; @@ -8,13 +8,13 @@ import androidx.annotation.Nullable; import com.google.gson.Gson; import com.google.gson.JsonParser; -import com.uiuios.aios.alarm.AlarmUtils; import java.io.Serializable; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import java.util.Objects; public class AlarmClockData implements Serializable { private static final long serialVersionUID = -5856502480745183157L; @@ -26,10 +26,14 @@ public class AlarmClockData implements Serializable { String voice;//语音文件地址 String voice_md5; String file;//图片或视频文件地址 + String file_md5; int remind_type; int is_onoff;//0关闭 1开启 boolean finished = false; + boolean is_local = false; + boolean edited = false; + boolean deleted = false; public int getId() { return id; @@ -87,6 +91,14 @@ public class AlarmClockData implements Serializable { this.file = file; } + public String getFile_md5() { + return file_md5; + } + + public void setFile_md5(String file_md5) { + this.file_md5 = file_md5; + } + public boolean isFinished() { return finished; } @@ -111,6 +123,30 @@ public class AlarmClockData implements Serializable { this.is_onoff = is_onoff; } + public boolean isIs_local() { + return is_local; + } + + public void setIs_local(boolean is_local) { + this.is_local = is_local; + } + + public boolean isEdited() { + return edited; + } + + public void setEdited(boolean edited) { + this.edited = edited; + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + public long getTimeStamp() { if (TextUtils.isEmpty(time)) { return 0L; @@ -151,11 +187,12 @@ public class AlarmClockData implements Serializable { if (!(obj instanceof AlarmClockData)) return false; if (id != ((AlarmClockData) obj).id) return false; if (type != ((AlarmClockData) obj).type) return false; - if (!time.equals(((AlarmClockData) obj).time)) return false; - if (!title.equals(((AlarmClockData) obj).title)) return false; - if (!voice.equals(((AlarmClockData) obj).voice)) return false; - if (!voice_md5.equals(((AlarmClockData) obj).voice_md5)) return false; - if (!file.equals(((AlarmClockData) obj).file)) return false; + if (!Objects.equals(time, ((AlarmClockData) obj).time)) return false; + if (!Objects.equals(title, ((AlarmClockData) obj).title)) return false; + if (!Objects.equals(voice, ((AlarmClockData) obj).voice)) return false; + if (!Objects.equals(voice_md5, ((AlarmClockData) obj).voice_md5)) return false; + if (!Objects.equals(file, ((AlarmClockData) obj).file)) return false; + if (!Objects.equals(file_md5, ((AlarmClockData) obj).file_md5)) return false; if (remind_type != ((AlarmClockData) obj).remind_type) return false; if (is_onoff != ((AlarmClockData) obj).is_onoff) return false; diff --git a/app/src/main/java/com/uiuios/aios/alarm/AlarmOpenHelper.java b/app/src/main/java/com/uiuios/aios/alarm/AlarmOpenHelper.java index ce0dd8f..7a26a6f 100644 --- a/app/src/main/java/com/uiuios/aios/alarm/AlarmOpenHelper.java +++ b/app/src/main/java/com/uiuios/aios/alarm/AlarmOpenHelper.java @@ -3,15 +3,15 @@ package com.uiuios.aios.alarm; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; -import android.os.Environment; import java.io.File; public class AlarmOpenHelper extends SQLiteOpenHelper { - public static final int DATABASE_VERSION = 1; + public static final int DATABASE_VERSION = 2; public static final String DATABASE_NAME = "AlarmDatabase.db"; - public static final String DATABASE_FILE_NAME = Environment.getExternalStorageDirectory().getPath() + File.separator + DATABASE_NAME; + // public static final String DATABASE_FILE_NAME = Environment.getExternalStorageDirectory().getPath() + File.separator + DATABASE_NAME; + public static final String DATABASE_FILE_NAME = File.separator + DATABASE_NAME; public static final String TABLE_ALARM = " AlarmTable"; @@ -22,9 +22,15 @@ public class AlarmOpenHelper extends SQLiteOpenHelper { public static final String KEY_VOICE = "voice"; public static final String KEY_VOICE_MD5 = "voice_md5"; public static final String KEY_FILE = "file"; + public static final String KEY_FILE_MD5 = "file_md5"; public static final String KEY_REMIND_TYPE = "remind_type"; public static final String KEY_IS_ONOFF = "is_onoff"; + public static final String KEY_FINISHED = "finished"; + public static final String KEY_IS_LOCAL = "is_local"; + public static final String KEY_EDITED = "edited"; + public static final String KEY_DELETED = "deleted"; + String CREATE_ALARM_TABLE = "CREATE TABLE IF NOT EXISTS" + TABLE_ALARM + "(" @@ -35,9 +41,14 @@ public class AlarmOpenHelper extends SQLiteOpenHelper { + KEY_VOICE + " TEXT," + KEY_VOICE_MD5 + " TEXT," + KEY_FILE + " TEXT," + + KEY_FILE_MD5 + " TEXT," + KEY_REMIND_TYPE + " INTEGER," + KEY_IS_ONOFF + " INTEGER," - + KEY_FINISHED + " BOOLEAN DEFAULT 0" + + + KEY_FINISHED + " BOOLEAN DEFAULT 0," + + KEY_IS_LOCAL + " BOOLEAN DEFAULT 0," + + KEY_EDITED + " BOOLEAN DEFAULT 0," + + KEY_DELETED + " BOOLEAN DEFAULT 0" + ")"; public AlarmOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { @@ -51,10 +62,16 @@ public class AlarmOpenHelper extends SQLiteOpenHelper { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - if (oldVersion >= newVersion) { - return; + switch (oldVersion + 1) { + case 1: + db.execSQL(CREATE_ALARM_TABLE); // 执行修改表,添加字段的逻辑。 + case 2: + String sql = "ALTER TABLE " + TABLE_ALARM + " ADD COLUMN " + KEY_EDITED + " BOOLEAN DEFAULT 0"; + db.execSQL(sql); + String sql2 = "ALTER TABLE " + TABLE_ALARM + " ADD COLUMN " + KEY_DELETED + " BOOLEAN DEFAULT 0"; + db.execSQL(sql2); + String sql3 = "ALTER TABLE " + TABLE_ALARM + " ADD COLUMN " + KEY_FILE_MD5 + " TEXT"; + db.execSQL(sql3); } - db.execSQL("DROP TABLE IF EXISTS " + TABLE_ALARM); - onCreate(db); } } diff --git a/app/src/main/java/com/uiuios/aios/alarm/AlarmUtils.java b/app/src/main/java/com/uiuios/aios/alarm/AlarmUtils.java index 3ee4085..a9a87f8 100644 --- a/app/src/main/java/com/uiuios/aios/alarm/AlarmUtils.java +++ b/app/src/main/java/com/uiuios/aios/alarm/AlarmUtils.java @@ -13,8 +13,6 @@ import android.util.Log; import com.arialyy.aria.core.Aria; import com.blankj.utilcode.util.FileUtils; -import com.bumptech.glide.Glide; -import com.uiuios.aios.bean.AlarmClockData; import com.uiuios.aios.service.main.MainService; import com.uiuios.aios.utils.FileUtil; import com.uiuios.aios.utils.Utils; @@ -35,23 +33,33 @@ import java.util.Map; import java.util.TimeZone; public class AlarmUtils { + private static final String TAG = AlarmUtils.class.getSimpleName(); + @SuppressLint("StaticFieldLeak") private static AlarmUtils sInstance; - private static String TAG = AlarmUtils.class.getSimpleName(); private Context mContext; - private AlarmManager alarmManager; - private SQLiteDatabase db; + private AlarmManager mAlarmManager; + private SQLiteDatabase mDatabase; private AlarmOpenHelper mAlarmOpenHelper; + private HashSet pendingIntents; public static final int ONE_DAY_TIME = 1000 * 60 * 60 * 24; + /*一次性*/ + public static final int ONCE = 1; + /*每天*/ + public static final int LOOP = 2; + /*周一到周五*/ + public static final int WORKING_DAY = 3; + /*休息日*/ + public static final int OFF_DAY = 4; private AlarmUtils(Context context) { this.mContext = context; // this.mAlarmOpenHelper = new AlarmOpenHelper(context, AlarmOpenHelper.DATABASE_NAME, null, AlarmOpenHelper.DATABASE_VERSION); - this.mAlarmOpenHelper = new AlarmOpenHelper(context, AlarmOpenHelper.DATABASE_FILE_NAME, null, AlarmOpenHelper.DATABASE_VERSION); - this.db = mAlarmOpenHelper.getWritableDatabase(); - alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + this.mAlarmOpenHelper = new AlarmOpenHelper(context, mContext.getExternalCacheDir() + AlarmOpenHelper.DATABASE_FILE_NAME, null, AlarmOpenHelper.DATABASE_VERSION); + this.mDatabase = mAlarmOpenHelper.getWritableDatabase(); + this.mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); } public static void init(Context context) { @@ -65,15 +73,35 @@ public class AlarmUtils { public static AlarmUtils getInstance() { if (sInstance == null) { - throw new IllegalStateException("You must be init AmapManager first"); + throw new IllegalStateException("You must be init AlarmUtils first"); } return sInstance; } - private void open() { - if (db == null || !db.isOpen()) { - db = mAlarmOpenHelper.getWritableDatabase(); - } + private void openDatabase() { +// if (mDatabase == null || !mDatabase.isOpen()) { +// mDatabase = mAlarmOpenHelper.getWritableDatabase(); +// } + } + + private ContentValues getValuesFromAlarmClock(AlarmClockData alarmClockData) { + ContentValues values = new ContentValues(); + values.put(AlarmOpenHelper.KEY_ID, alarmClockData.getId()); + values.put(AlarmOpenHelper.KEY_TYPE, alarmClockData.getType()); + values.put(AlarmOpenHelper.KEY_TIME, alarmClockData.getTime()); + values.put(AlarmOpenHelper.KEY_TITLE, alarmClockData.getTitle()); + values.put(AlarmOpenHelper.KEY_VOICE, alarmClockData.getVoice()); + values.put(AlarmOpenHelper.KEY_VOICE_MD5, alarmClockData.getVoice_md5()); + values.put(AlarmOpenHelper.KEY_FILE, alarmClockData.getFile()); + values.put(AlarmOpenHelper.KEY_FILE_MD5, alarmClockData.getFile_md5()); + values.put(AlarmOpenHelper.KEY_REMIND_TYPE, alarmClockData.getRemind_type()); + values.put(AlarmOpenHelper.KEY_IS_ONOFF, alarmClockData.getIs_onoff()); + + values.put(AlarmOpenHelper.KEY_FINISHED, alarmClockData.isFinished()); + values.put(AlarmOpenHelper.KEY_IS_LOCAL, alarmClockData.isIs_local()); + values.put(AlarmOpenHelper.KEY_EDITED, alarmClockData.isEdited()); + values.put(AlarmOpenHelper.KEY_DELETED, alarmClockData.isDeleted()); + return values; } /** @@ -83,27 +111,19 @@ public class AlarmUtils { * @return */ public boolean addAlarmClock(AlarmClockData alarmClockData) { - open(); - ContentValues values = new ContentValues(); - values.put(AlarmOpenHelper.KEY_ID, alarmClockData.getId()); - values.put(AlarmOpenHelper.KEY_TYPE, alarmClockData.getType()); - values.put(AlarmOpenHelper.KEY_TIME, alarmClockData.getTime()); - values.put(AlarmOpenHelper.KEY_TITLE, alarmClockData.getTitle()); - values.put(AlarmOpenHelper.KEY_VOICE, alarmClockData.getVoice()); - values.put(AlarmOpenHelper.KEY_VOICE_MD5, alarmClockData.getVoice_md5()); - values.put(AlarmOpenHelper.KEY_FILE, alarmClockData.getFile()); - values.put(AlarmOpenHelper.KEY_REMIND_TYPE, alarmClockData.getRemind_type()); - values.put(AlarmOpenHelper.KEY_IS_ONOFF, alarmClockData.getIs_onoff()); + openDatabase(); + ContentValues values = getValuesFromAlarmClock(alarmClockData); long id = 0; - db.beginTransaction(); + mDatabase.beginTransaction(); try { - id = db.insert(AlarmOpenHelper.TABLE_ALARM, null, values); + id = mDatabase.insertWithOnConflict(AlarmOpenHelper.TABLE_ALARM, null, values, SQLiteDatabase.CONFLICT_REPLACE); + mDatabase.setTransactionSuccessful(); } catch (Exception e) { - db.setTransactionSuccessful(); + Log.e(TAG, "addAlarmClock: " + e.getMessage()); } finally { - db.endTransaction(); + mDatabase.endTransaction(); } - db.close(); + setAlarm(alarmClockData); return id > 0; } @@ -115,28 +135,53 @@ public class AlarmUtils { * @return */ public boolean updateAlarmClock(AlarmClockData alarmClockData) { - open(); - ContentValues values = new ContentValues(); - values.put(AlarmOpenHelper.KEY_ID, alarmClockData.getId()); - values.put(AlarmOpenHelper.KEY_TYPE, alarmClockData.getType()); - values.put(AlarmOpenHelper.KEY_TIME, alarmClockData.getTime()); - values.put(AlarmOpenHelper.KEY_TITLE, alarmClockData.getTitle()); - values.put(AlarmOpenHelper.KEY_VOICE, alarmClockData.getVoice()); - values.put(AlarmOpenHelper.KEY_VOICE_MD5, alarmClockData.getVoice_md5()); - values.put(AlarmOpenHelper.KEY_FILE, alarmClockData.getFile()); - values.put(AlarmOpenHelper.KEY_REMIND_TYPE, alarmClockData.getRemind_type()); - values.put(AlarmOpenHelper.KEY_IS_ONOFF, alarmClockData.getIs_onoff()); + openDatabase(); + AlarmClockData old = getDatabaseSingleAlarm(alarmClockData); + if (old != null) { + PendingIntent pendingIntent = getPendingIntent(old); + if (pendingIntent != null) { + mAlarmManager.cancel(pendingIntent); + } + } + ContentValues values = getValuesFromAlarmClock(alarmClockData); long id = 0; - db.beginTransaction(); + mDatabase.beginTransaction(); try { - id = db.insertWithOnConflict(AlarmOpenHelper.TABLE_ALARM, null, values, SQLiteDatabase.CONFLICT_REPLACE); - db.setTransactionSuccessful(); + id = mDatabase.insertWithOnConflict(AlarmOpenHelper.TABLE_ALARM, null, values, SQLiteDatabase.CONFLICT_REPLACE); + mDatabase.setTransactionSuccessful(); } catch (Exception e) { Log.e(TAG, "updateAlarmClock: " + e.getMessage()); } finally { - db.endTransaction(); + mDatabase.endTransaction(); } - db.close(); + setAlarm(alarmClockData); + return id > 0; + } + + public boolean updateAlarmClock(AlarmClockData alarmClockData, int newId) { + openDatabase(); + int oldId = alarmClockData.getId(); + AlarmClockData old = getDatabaseSingleAlarm(alarmClockData); + if (old != null) { +// deleteAlarmClock(oldId); + PendingIntent pendingIntent = getPendingIntent(old); + if (pendingIntent != null) { + mAlarmManager.cancel(pendingIntent); + } + } + alarmClockData.setId(newId); + ContentValues values = getValuesFromAlarmClock(alarmClockData); + long id = 0; + mDatabase.beginTransaction(); + try { + id = mDatabase.update(AlarmOpenHelper.TABLE_ALARM, values, "id=" + oldId, null); + mDatabase.setTransactionSuccessful(); + } catch (Exception e) { + Log.e(TAG, "updateAlarmClock: " + e.getMessage()); + } finally { + mDatabase.endTransaction(); + } + setAlarm(alarmClockData); return id > 0; } @@ -145,35 +190,24 @@ public class AlarmUtils { * * @param list */ - public void insertListValues(List list) { - open(); + public void insertAlarmClockList(List list) { + openDatabase(); List contentValuesList = new ArrayList<>(); for (AlarmClockData alarmClockData : list) { - ContentValues values = new ContentValues(); - values.put(AlarmOpenHelper.KEY_ID, alarmClockData.getId()); - values.put(AlarmOpenHelper.KEY_TYPE, alarmClockData.getType()); - values.put(AlarmOpenHelper.KEY_TIME, alarmClockData.getTime()); - values.put(AlarmOpenHelper.KEY_TITLE, alarmClockData.getTitle()); - values.put(AlarmOpenHelper.KEY_VOICE, alarmClockData.getVoice()); - values.put(AlarmOpenHelper.KEY_VOICE_MD5, alarmClockData.getVoice_md5()); - values.put(AlarmOpenHelper.KEY_FILE, alarmClockData.getFile()); - values.put(AlarmOpenHelper.KEY_REMIND_TYPE, alarmClockData.getRemind_type()); - values.put(AlarmOpenHelper.KEY_IS_ONOFF, alarmClockData.getIs_onoff()); - values.put(AlarmOpenHelper.KEY_FINISHED, alarmClockData.isFinished()); + ContentValues values = getValuesFromAlarmClock(alarmClockData); contentValuesList.add(values); } - db.beginTransaction(); + mDatabase.beginTransaction(); try { for (ContentValues v : contentValuesList) { - db.insertWithOnConflict(AlarmOpenHelper.TABLE_ALARM, null, v, SQLiteDatabase.CONFLICT_REPLACE); + mDatabase.insertWithOnConflict(AlarmOpenHelper.TABLE_ALARM, null, v, SQLiteDatabase.CONFLICT_REPLACE); } - db.setTransactionSuccessful(); + mDatabase.setTransactionSuccessful(); } catch (Exception e) { Log.e(TAG, "insertListValues: " + e.getMessage()); } finally { - db.endTransaction(); + mDatabase.endTransaction(); } - db.close(); } /** @@ -184,36 +218,42 @@ public class AlarmUtils { */ public boolean deleteAlarmClock(AlarmClockData alarmClockData) { if (alarmClockData == null) { - return false; + return true; + } + PendingIntent pendingIntent = getPendingIntent(alarmClockData); + if (pendingIntent != null) { + mAlarmManager.cancel(pendingIntent); } return deleteAlarmClock(alarmClockData.getId()); } public boolean deleteAlarmClock(int RowID) { - open(); + openDatabase(); long id = 0; - db.beginTransaction(); + mDatabase.beginTransaction(); try { - id = db.delete(AlarmOpenHelper.TABLE_ALARM, "id =" + RowID, null); - db.setTransactionSuccessful(); + id = mDatabase.delete(AlarmOpenHelper.TABLE_ALARM, " id =" + RowID, null); + mDatabase.setTransactionSuccessful(); } catch (Exception e) { Log.e(TAG, "deleteAlarmClock: " + e.getMessage()); } finally { - db.endTransaction(); + mDatabase.endTransaction(); } - db.close(); return id > 0; } + /** + * 删除所有闹钟 + */ public void deleteAllAlarmClock() { - HashSet pendingIntents = getOldPendingIntents(); + HashSet pendingIntents = getOldPendingIntentsSet(); Iterator pendingIntentIterator = pendingIntents.iterator(); while (pendingIntentIterator.hasNext()) { PendingIntent pendingIntent = pendingIntentIterator.next(); - alarmManager.cancel(pendingIntent); + mAlarmManager.cancel(pendingIntent); pendingIntentIterator.remove(); } - List alarmClockData = getAllAlarms(); + List alarmClockData = getDatabaseAlarms(); for (AlarmClockData data : alarmClockData) { deleteAlarmClock(data.getId()); } @@ -224,12 +264,11 @@ public class AlarmUtils { * * @return */ - public List getAllAlarms() { - open(); + public List getDatabaseAlarms() { + openDatabase(); List list = new ArrayList<>(); String selectQuery = "SELECT * FROM " + AlarmOpenHelper.TABLE_ALARM; - open(); - Cursor cursor = db.rawQuery(selectQuery, null); + Cursor cursor = mDatabase.rawQuery(selectQuery, null); if (cursor.moveToFirst()) { do { AlarmClockData alarmClockData = new AlarmClockData(); @@ -240,23 +279,139 @@ public class AlarmUtils { alarmClockData.setVoice(cursor.getString(4)); alarmClockData.setVoice_md5(cursor.getString(5)); alarmClockData.setFile(cursor.getString(6)); - alarmClockData.setRemind_type(cursor.getInt(7)); - alarmClockData.setIs_onoff(cursor.getInt(8)); - if (cursor.getInt(9) == 1) { - alarmClockData.setFinished(true); - } else { - alarmClockData.setFinished(false); - } + alarmClockData.setFile_md5(cursor.getString(7)); + alarmClockData.setRemind_type(cursor.getInt(8)); + alarmClockData.setIs_onoff(cursor.getInt(9)); + alarmClockData.setFinished(cursor.getInt(10) == 1); + alarmClockData.setIs_local(cursor.getInt(11) == 1); + alarmClockData.setEdited(cursor.getInt(12) == 1); + alarmClockData.setDeleted(cursor.getInt(13) == 1); list.add(alarmClockData); } while (cursor.moveToNext()); } cursor.close(); - db.close(); return list; } + /** + * @return 获取单个闹钟 + */ + public AlarmClockData getDatabaseSingleAlarm(AlarmClockData data) { + openDatabase(); + List list = new ArrayList<>(); + String selectQuery = "SELECT * FROM " + AlarmOpenHelper.TABLE_ALARM + " where id =" + data.getId(); + Cursor cursor = mDatabase.rawQuery(selectQuery, null); + if (cursor.moveToFirst()) { + do { + AlarmClockData alarmClockData = new AlarmClockData(); + alarmClockData.setId(Integer.parseInt(cursor.getString(0))); + alarmClockData.setType(cursor.getInt(1)); + alarmClockData.setTime(cursor.getString(2)); + alarmClockData.setTitle(cursor.getString(3)); + alarmClockData.setVoice(cursor.getString(4)); + alarmClockData.setVoice_md5(cursor.getString(5)); + alarmClockData.setFile(cursor.getString(6)); + alarmClockData.setFile_md5(cursor.getString(7)); + alarmClockData.setRemind_type(cursor.getInt(8)); + alarmClockData.setIs_onoff(cursor.getInt(9)); + alarmClockData.setFinished(cursor.getInt(10) == 1); + alarmClockData.setIs_local(cursor.getInt(11) == 1); + alarmClockData.setEdited(cursor.getInt(12) == 1); + alarmClockData.setDeleted(cursor.getInt(13) == 1); + list.add(alarmClockData); + } while (cursor.moveToNext()); + } + cursor.close(); + return list.size() == 0 ? null : list.get(0); + } + + public AlarmClockData getDatabaseSingleAlarm(int id) { + openDatabase(); + List list = new ArrayList<>(); + String selectQuery = "SELECT * FROM " + AlarmOpenHelper.TABLE_ALARM + " where id =" + id; + Cursor cursor = mDatabase.rawQuery(selectQuery, null); + if (cursor.moveToFirst()) { + do { + AlarmClockData alarmClockData = new AlarmClockData(); + alarmClockData.setId(Integer.parseInt(cursor.getString(0))); + alarmClockData.setType(cursor.getInt(1)); + alarmClockData.setTime(cursor.getString(2)); + alarmClockData.setTitle(cursor.getString(3)); + alarmClockData.setVoice(cursor.getString(4)); + alarmClockData.setVoice_md5(cursor.getString(5)); + alarmClockData.setFile(cursor.getString(6)); + alarmClockData.setFile_md5(cursor.getString(7)); + alarmClockData.setRemind_type(cursor.getInt(8)); + alarmClockData.setIs_onoff(cursor.getInt(9)); + alarmClockData.setFinished(cursor.getInt(10) == 1); + alarmClockData.setIs_local(cursor.getInt(11) == 1); + alarmClockData.setEdited(cursor.getInt(12) == 1); + alarmClockData.setDeleted(cursor.getInt(13) == 1); + list.add(alarmClockData); + } while (cursor.moveToNext()); + } + cursor.close(); + return list.size() == 0 ? null : list.get(0); + } + + public List getDeletedAlarm() { + openDatabase(); + List list = new ArrayList<>(); + String selectQuery = "SELECT * FROM " + AlarmOpenHelper.TABLE_ALARM + " where deleted = 1"; + Cursor cursor = mDatabase.rawQuery(selectQuery, null); + if (cursor.moveToFirst()) { + do { + AlarmClockData alarmClockData = new AlarmClockData(); + alarmClockData.setId(Integer.parseInt(cursor.getString(0))); + alarmClockData.setType(cursor.getInt(1)); + alarmClockData.setTime(cursor.getString(2)); + alarmClockData.setTitle(cursor.getString(3)); + alarmClockData.setVoice(cursor.getString(4)); + alarmClockData.setVoice_md5(cursor.getString(5)); + alarmClockData.setFile(cursor.getString(6)); + alarmClockData.setFile_md5(cursor.getString(7)); + alarmClockData.setRemind_type(cursor.getInt(8)); + alarmClockData.setIs_onoff(cursor.getInt(9)); + alarmClockData.setFinished(cursor.getInt(10) == 1); + alarmClockData.setIs_local(cursor.getInt(11) == 1); + alarmClockData.setEdited(cursor.getInt(12) == 1); + alarmClockData.setDeleted(cursor.getInt(13) == 1); + list.add(alarmClockData); + } while (cursor.moveToNext()); + } + cursor.close(); + return list; + } + + public List getLocalAddAlarm() { + openDatabase(); + List list = new ArrayList<>(); + String selectQuery = "SELECT * FROM " + AlarmOpenHelper.TABLE_ALARM + " where is_local = 1"; + Cursor cursor = mDatabase.rawQuery(selectQuery, null); + if (cursor.moveToFirst()) { + do { + AlarmClockData alarmClockData = new AlarmClockData(); + alarmClockData.setId(Integer.parseInt(cursor.getString(0))); + alarmClockData.setType(cursor.getInt(1)); + alarmClockData.setTime(cursor.getString(2)); + alarmClockData.setTitle(cursor.getString(3)); + alarmClockData.setVoice(cursor.getString(4)); + alarmClockData.setVoice_md5(cursor.getString(5)); + alarmClockData.setFile(cursor.getString(6)); + alarmClockData.setFile_md5(cursor.getString(7)); + alarmClockData.setRemind_type(cursor.getInt(8)); + alarmClockData.setIs_onoff(cursor.getInt(9)); + alarmClockData.setFinished(cursor.getInt(10) == 1); + alarmClockData.setIs_local(cursor.getInt(11) == 1); + alarmClockData.setEdited(cursor.getInt(12) == 1); + alarmClockData.setDeleted(cursor.getInt(13) == 1); + list.add(alarmClockData); + } while (cursor.moveToNext()); + } + cursor.close(); + return list; + } - private HashSet pendingIntents; /** * 设置闹钟列表 @@ -265,58 +420,54 @@ public class AlarmUtils { */ public void setAlarmClockData(List data) { if (pendingIntents == null) { - pendingIntents = getOldPendingIntents(); + pendingIntents = getOldPendingIntentsSet(); } Iterator pendingIntentIterator = pendingIntents.iterator(); while (pendingIntentIterator.hasNext()) { PendingIntent pendingIntent = pendingIntentIterator.next(); - alarmManager.cancel(pendingIntent); + mAlarmManager.cancel(pendingIntent); pendingIntentIterator.remove(); } -// for (PendingIntent pendingIntent : pendingIntents) { -// -// } List newData = mergeData(data); for (AlarmClockData clockData : newData) { setAlarm(clockData); checkResource(clockData.getFile()); } - insertListValues(newData); + insertAlarmClockList(newData); } + /** + * @param url 下载资源 + */ private void checkResource(String url) { - if (TextUtils.isEmpty(url)) + if (TextUtils.isEmpty(url)) { return; + } String fileName = url.substring(url.lastIndexOf("/") + 1, url.length()); - if (FileUtil.isVideoFile(fileName)) { - String realPath = Utils.getDownLoadPath(mContext) + fileName; - File file = new File(realPath); - if (!file.exists()) { - Aria.download(this) - .load(url) //读取下载地址 - .setFilePath(Utils.getDownLoadPath(mContext) + fileName) - // .ignoreFilePathOccupy() - .create(); //启动下载} - } - }else if (FileUtil.isPictureFile(fileName)){ - Glide.with(mContext).load(url); + String realPath = Utils.getDownLoadPath(mContext) + fileName; + File file = new File(realPath); + if (!file.exists()) { + Aria.download(this) + .load(url) //读取下载地址 + .setFilePath(Utils.getDownLoadPath(mContext) + fileName) + .create(); //启动下载} } } /** * 合并闹钟列表,删除不存在闹钟 * - * @param alarmClockDataList - * @return + * @param newAlarmClockDataList + * @return 新增的闹钟 */ - private List mergeData(List alarmClockDataList) { + private List mergeData(List newAlarmClockDataList) { HashMap alarmClockDataMap = new HashMap<>(); - if (alarmClockDataList != null) { - for (AlarmClockData alarmClockData : alarmClockDataList) { + if (newAlarmClockDataList != null) { + for (AlarmClockData alarmClockData : newAlarmClockDataList) { alarmClockDataMap.put(alarmClockData.getId(), alarmClockData); } } - HashMap oldData = getOldData(); + HashMap oldData = getOldDataMap(); List deleteData = new ArrayList<>(); for (Map.Entry entry : oldData.entrySet()) { if (alarmClockDataMap.get(entry.getKey()) == null) { @@ -324,14 +475,18 @@ public class AlarmUtils { } } for (AlarmClockData alarmClockData : deleteData) { + if (alarmClockData.isIs_local() || alarmClockData.deleted) { + Log.e(TAG, "mergeData: skip " + alarmClockData.getId()); + continue; + } deleteAlarmClock(alarmClockData); } List newData = new ArrayList<>(); - if (alarmClockDataList == null) { + if (newAlarmClockDataList == null) { return newData; } - for (AlarmClockData alarm : alarmClockDataList) { + for (AlarmClockData alarm : newAlarmClockDataList) { AlarmClockData oldAlarm = oldData.get(alarm.getId()); if (oldAlarm == null) { newData.add(alarm); @@ -353,53 +508,48 @@ public class AlarmUtils { * @return */ public boolean updateAlarmFinished(AlarmClockData alarmClockData) { - open(); - ContentValues values = new ContentValues(); - values.put(AlarmOpenHelper.KEY_ID, alarmClockData.getId()); - values.put(AlarmOpenHelper.KEY_TYPE, alarmClockData.getType()); - values.put(AlarmOpenHelper.KEY_TIME, alarmClockData.getTime()); - values.put(AlarmOpenHelper.KEY_TITLE, alarmClockData.getTitle()); - values.put(AlarmOpenHelper.KEY_VOICE, alarmClockData.getVoice()); - values.put(AlarmOpenHelper.KEY_VOICE_MD5, alarmClockData.getVoice_md5()); - values.put(AlarmOpenHelper.KEY_FILE, alarmClockData.getFile()); - values.put(AlarmOpenHelper.KEY_REMIND_TYPE, alarmClockData.getRemind_type()); - values.put(AlarmOpenHelper.KEY_IS_ONOFF, alarmClockData.getIs_onoff()); - values.put(AlarmOpenHelper.KEY_FINISHED, alarmClockData.isFinished()); + openDatabase(); + ContentValues values = getValuesFromAlarmClock(alarmClockData); long id = 0; - db.beginTransaction(); + mDatabase.beginTransaction(); try { - id = db.update(AlarmOpenHelper.TABLE_ALARM, values, AlarmOpenHelper.KEY_ID + "=?", new String[]{String.valueOf(alarmClockData.getId())}); - db.setTransactionSuccessful(); + id = mDatabase.update(AlarmOpenHelper.TABLE_ALARM, values, AlarmOpenHelper.KEY_ID + "=?", new String[]{String.valueOf(alarmClockData.getId())}); + mDatabase.setTransactionSuccessful(); } catch (Exception e) { Log.e(TAG, "updateAlarmFinished: " + e.getMessage()); } finally { - db.endTransaction(); + mDatabase.endTransaction(); } - db.close(); return id > 0; } - public HashMap getOldData() { - List alarmClockData = getAllAlarms(); - if (alarmClockData == null || alarmClockData.size() == 0) { - return new HashMap<>(); - } else { - HashMap hashMap = new HashMap<>(); + public List getOldData() { + List alarmClockData = new ArrayList<>(); + List dataBaseAlarms = getDatabaseAlarms(); + if (dataBaseAlarms != null && dataBaseAlarms.size() != 0) { + alarmClockData.addAll(dataBaseAlarms); + } + return alarmClockData; + } + + public HashMap getOldDataMap() { + List alarmClockData = getOldData(); + HashMap hashMap = new HashMap<>(); + if (alarmClockData.size() != 0) { for (AlarmClockData clockData : alarmClockData) { hashMap.put(clockData.getId(), clockData); } - return hashMap; } + return hashMap; } - /** * 获取最近一次的闹钟 * * @return */ public AlarmClockData getRecentAlarmClock() { - List alarmClockData = getAllAlarms(); + List alarmClockData = getDatabaseAlarms(); if (alarmClockData == null || alarmClockData.size() == 0) { return null; } else { @@ -417,15 +567,21 @@ public class AlarmUtils { } } - private HashSet getOldPendingIntents() { + private HashSet getOldPendingIntentsSet() { HashSet pendingIntents = new HashSet<>(); - HashMap data = getOldData(); + HashMap data = getOldDataMap(); for (AlarmClockData alarmClockData : data.values()) { pendingIntents.add(getPendingIntent(alarmClockData)); } return pendingIntents; } + /** + * 获取已设置闹钟的PendingIntent + * + * @param alarmClock + * @return + */ private PendingIntent getPendingIntent(AlarmClockData alarmClock) { Intent intent = new Intent(MainService.ALARMWAKEUP); intent.putExtra("title", alarmClock.getTitle()); @@ -475,14 +631,6 @@ public class AlarmUtils { return zeroTime; } - /*一次性*/ - public static final int ONCE = 1; - /*每天*/ - public static final int LOOP = 2; - /*周一到周五*/ - public static final int WORKING_DAY = 3; - /*休息日*/ - public static final int OFF_DAY = 4; /** * 设置闹钟 @@ -490,6 +638,9 @@ public class AlarmUtils { * @param alarm */ public void setAlarm(AlarmClockData alarm) { + if (pendingIntents == null) { + pendingIntents = getOldPendingIntentsSet(); + } int id = alarm.getId(); int type = alarm.getType(); String timeString = alarm.getTime(); @@ -498,10 +649,17 @@ public class AlarmUtils { long timeStamp = getTimestamp(timeString); Log.e(TAG, "setAlarm: " + timeStamp); boolean finished = alarm.isFinished(); - String url = alarm.getVoice(); - String md5 = alarm.getVoice_md5(); - if (!TextUtils.isEmpty(url)) { - ariaDownload(url, md5); + String voiceUrl = alarm.getVoice(); + String voiceMd5 = alarm.getVoice_md5(); + if (!TextUtils.isEmpty(voiceUrl)) { + if (!FileUtil.isLocalPath(voiceUrl)) + ariaDownload(voiceUrl, voiceMd5); + } + String fileUrl = alarm.getFile(); + String fileMd5 = alarm.getFile_md5(); + if (!TextUtils.isEmpty(fileUrl)) { + if (!FileUtil.isLocalPath(fileUrl)) + ariaDownload(fileUrl, fileMd5); } switch (type) { case ONCE: @@ -540,7 +698,7 @@ public class AlarmUtils { intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); - alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); + mAlarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); Log.e(TAG, "setOnceAlarm: " + "id: " + requestCode + " title: " + extra + " timeString: " + timestamp); } @@ -559,7 +717,7 @@ public class AlarmUtils { intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); - alarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); + mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); Log.e(TAG, "setDayLoopAlarm: " + "title: " + extra + " timeString: " + timestamp); // setLoopAlarm(action, extra, requestCode, AlarmManager.INTERVAL_DAY, timestamp); } @@ -585,7 +743,7 @@ public class AlarmUtils { intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); - alarmManager.setWindow(AlarmManager.RTC_WAKEUP, timestamp, intervalMillis, startPendingIntent); + mAlarmManager.setWindow(AlarmManager.RTC_WAKEUP, timestamp, intervalMillis, startPendingIntent); Log.e(TAG, "setLoopAlarm: " + "title: " + extra + " timeString: " + timestamp); } @@ -609,7 +767,7 @@ public class AlarmUtils { intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); - alarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); + mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); Log.e(TAG, "setWorkDayAlarm: " + "title: " + extra + " timeString: " + timestamp); } @@ -634,7 +792,7 @@ public class AlarmUtils { intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); - alarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); + mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); Log.e(TAG, "setOffDayAlarm: " + "title: " + extra + " timeString: " + timestamp); } @@ -646,7 +804,7 @@ public class AlarmUtils { String fileMD5 = FileUtils.getFileMD5ToString(file); Log.e("ariaDownload", "fileOnlineMD5=" + md5); Log.e("ariaDownload", "fileMD5=" + fileMD5); - if (!md5.equals(fileMD5)) { + if (!md5.equalsIgnoreCase(fileMD5)) { Aria.download(this) .load(url) //读取下载地址 .setFilePath(Utils.getDownLoadPath(mContext) + fileName) @@ -666,5 +824,23 @@ public class AlarmUtils { } } + public void ariaDownload(String url) { + if (FileUtil.isLocalPath(url)) { + return; + } + String fileName = Utils.getFileNamefromURL(url); + File file = new File(Utils.getDownLoadPath(mContext) + fileName); + if (file.exists() && !file.isDirectory()) { + String fileMD5 = FileUtils.getFileMD5ToString(file); + Log.e("ariaDownload", "fileMD5=" + fileMD5); + Log.e("ariaDownload", "fileName = " + fileName + " exists"); + } else { + Aria.download(this) + .load(url) //读取下载地址 + .setFilePath(Utils.getDownLoadPath(mContext) + fileName) + .create(); //启动下载} + } + } + } diff --git a/app/src/main/java/com/uiuios/aios/base/BaseApplication.java b/app/src/main/java/com/uiuios/aios/base/BaseApplication.java index a6fbaf8..2c84ca7 100644 --- a/app/src/main/java/com/uiuios/aios/base/BaseApplication.java +++ b/app/src/main/java/com/uiuios/aios/base/BaseApplication.java @@ -29,6 +29,7 @@ import com.uiuios.aios.service.main.MainService; import com.uiuios.aios.utils.AppUsedTimeUtils; import com.uiuios.aios.utils.JGYUtils; import com.uiuios.aios.utils.Utils; +import com.uiuios.aios.utils.WiFiUtils; import java.util.ArrayList; import java.util.List; @@ -52,6 +53,7 @@ public class BaseApplication extends Application { Aria.init(this); Aria.get(this).getDownloadConfig().setMaxTaskNum(1); Aria.get(this).getDownloadConfig().setConvertSpeed(true); + WiFiUtils.init(this); AppUsedTimeUtils.init(this); AlarmUtils.init(this); HeConfig.init("HE2210211540591362", "fe42a7bb59b14eefb27eea4fb2c40e99"); diff --git a/app/src/main/java/com/uiuios/aios/base/BaseLifecycleActivity.java b/app/src/main/java/com/uiuios/aios/base/BaseLifecycleActivity.java new file mode 100644 index 0000000..fe530da --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/base/BaseLifecycleActivity.java @@ -0,0 +1,116 @@ +package com.uiuios.aios.base; + +import android.os.Bundle; + +import androidx.annotation.CallSuper; +import androidx.annotation.CheckResult; +import androidx.annotation.ContentView; +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.trello.rxlifecycle4.LifecycleProvider; +import com.trello.rxlifecycle4.LifecycleTransformer; +import com.trello.rxlifecycle4.RxLifecycle; +import com.trello.rxlifecycle4.android.ActivityEvent; +import com.trello.rxlifecycle4.android.RxLifecycleAndroid; + +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.subjects.BehaviorSubject; + + +public abstract class BaseLifecycleActivity extends AppCompatActivity implements LifecycleProvider { + public final BehaviorSubject lifecycleSubject = BehaviorSubject.create(); + + public BaseLifecycleActivity() { + super(); + } + + @ContentView + public BaseLifecycleActivity(@LayoutRes int contentLayoutId) { + super(contentLayoutId); + } + + @Override + @NonNull + @CheckResult + public final Observable lifecycle() { + return lifecycleSubject.hide(); + } + + @Override + @NonNull + @CheckResult + public final LifecycleTransformer bindUntilEvent(@NonNull ActivityEvent event) { + return RxLifecycle.bindUntilEvent(lifecycleSubject, event); + } + + @Override + @NonNull + @CheckResult + public final LifecycleTransformer bindToLifecycle() { + return RxLifecycleAndroid.bindActivity(lifecycleSubject); + } + + @Override + @CallSuper + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + lifecycleSubject.onNext(ActivityEvent.CREATE); + setContentView(this.getLayoutId()); + initView(); + initData(); + } + + /** + * 设置布局 + */ + public abstract int getLayoutId(); + + /** + * 初始化视图 + */ + public abstract void initView(); + + + /** + * 初始化数据 + */ + public abstract void initData(); + + @Override + @CallSuper + protected void onStart() { + super.onStart(); + lifecycleSubject.onNext(ActivityEvent.START); + } + + @Override + @CallSuper + protected void onResume() { + super.onResume(); + lifecycleSubject.onNext(ActivityEvent.RESUME); + } + + @Override + @CallSuper + protected void onPause() { + lifecycleSubject.onNext(ActivityEvent.PAUSE); + super.onPause(); + } + + @Override + @CallSuper + protected void onStop() { + lifecycleSubject.onNext(ActivityEvent.STOP); + super.onStop(); + } + + @Override + @CallSuper + protected void onDestroy() { + lifecycleSubject.onNext(ActivityEvent.DESTROY); + super.onDestroy(); + } +} diff --git a/app/src/main/java/com/uiuios/aios/base/BaseLightLifecycleActivity.java b/app/src/main/java/com/uiuios/aios/base/BaseLightLifecycleActivity.java new file mode 100644 index 0000000..2a33559 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/base/BaseLightLifecycleActivity.java @@ -0,0 +1,115 @@ +package com.uiuios.aios.base; + +import android.os.Bundle; + +import androidx.annotation.CallSuper; +import androidx.annotation.CheckResult; +import androidx.annotation.ContentView; +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.trello.rxlifecycle4.LifecycleProvider; +import com.trello.rxlifecycle4.LifecycleTransformer; +import com.trello.rxlifecycle4.RxLifecycle; +import com.trello.rxlifecycle4.android.ActivityEvent; +import com.trello.rxlifecycle4.android.RxLifecycleAndroid; + +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.subjects.BehaviorSubject; + +public abstract class BaseLightLifecycleActivity extends AppCompatActivity implements LifecycleProvider { + public final BehaviorSubject lifecycleSubject = BehaviorSubject.create(); + + public BaseLightLifecycleActivity() { + super(); + } + + @ContentView + public BaseLightLifecycleActivity(@LayoutRes int contentLayoutId) { + super(contentLayoutId); + } + + @Override + @NonNull + @CheckResult + public final Observable lifecycle() { + return lifecycleSubject.hide(); + } + + @Override + @NonNull + @CheckResult + public final LifecycleTransformer bindUntilEvent(@NonNull ActivityEvent event) { + return RxLifecycle.bindUntilEvent(lifecycleSubject, event); + } + + @Override + @NonNull + @CheckResult + public final LifecycleTransformer bindToLifecycle() { + return RxLifecycleAndroid.bindActivity(lifecycleSubject); + } + + @Override + @CallSuper + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + lifecycleSubject.onNext(ActivityEvent.CREATE); + setContentView(this.getLayoutId()); + initView(); + initData(); + } + + /** + * 设置布局 + */ + public abstract int getLayoutId(); + + /** + * 初始化视图 + */ + public abstract void initView(); + + + /** + * 初始化数据 + */ + public abstract void initData(); + + @Override + @CallSuper + protected void onStart() { + super.onStart(); + lifecycleSubject.onNext(ActivityEvent.START); + } + + @Override + @CallSuper + protected void onResume() { + super.onResume(); + lifecycleSubject.onNext(ActivityEvent.RESUME); + } + + @Override + @CallSuper + protected void onPause() { + lifecycleSubject.onNext(ActivityEvent.PAUSE); + super.onPause(); + } + + @Override + @CallSuper + protected void onStop() { + lifecycleSubject.onNext(ActivityEvent.STOP); + super.onStop(); + } + + @Override + @CallSuper + protected void onDestroy() { + lifecycleSubject.onNext(ActivityEvent.DESTROY); + super.onDestroy(); + } +} diff --git a/app/src/main/java/com/uiuios/aios/bean/AlarmClockId.java b/app/src/main/java/com/uiuios/aios/bean/AlarmClockId.java new file mode 100644 index 0000000..d4ec732 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/bean/AlarmClockId.java @@ -0,0 +1,16 @@ +package com.uiuios.aios.bean; + +import java.io.Serializable; + +public class AlarmClockId implements Serializable { + private static final long serialVersionUID = 4423679466957746841L; + int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/app/src/main/java/com/uiuios/aios/bean/WiFiInfo.java b/app/src/main/java/com/uiuios/aios/bean/WiFiInfo.java new file mode 100644 index 0000000..26c215e --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/bean/WiFiInfo.java @@ -0,0 +1,62 @@ +package com.uiuios.aios.bean; + +import java.io.Serializable; + +public class WiFiInfo implements Serializable { + private static final long serialVersionUID = 2429102475725706816L; + + String SSID; + String BSSID; + int level; + boolean connected; + boolean isSaved; + boolean isAvailable; + + public String getSSID() { + return SSID; + } + + public void setSSID(String SSID) { + this.SSID = SSID; + } + + public String getBSSID() { + return BSSID; + } + + public void setBSSID(String BSSID) { + this.BSSID = BSSID; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public boolean isConnected() { + return connected; + } + + public void setConnected(boolean connected) { + this.connected = connected; + } + + public boolean isSaved() { + return isSaved; + } + + public void setSaved(boolean saved) { + isSaved = saved; + } + + public boolean isAvailable() { + return isAvailable; + } + + public void setAvailable(boolean available) { + isAvailable = available; + } +} diff --git a/app/src/main/java/com/uiuios/aios/dialog/DeleWifiDialog.java b/app/src/main/java/com/uiuios/aios/dialog/DeleWifiDialog.java new file mode 100644 index 0000000..e26f9de --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/dialog/DeleWifiDialog.java @@ -0,0 +1,246 @@ +package com.uiuios.aios.dialog; + + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import com.uiuios.aios.R; + + +/** + * description:自定义dialog + */ + +public class DeleWifiDialog extends AlertDialog { + /** + * 显示的图片 + */ + private ImageView imageIv; + + /** + * 显示的标题 + */ + private TextView titleTv; + + /** + * 显示的消息 + */ + private TextView messageTv; + + /** + * 确认和取消按钮 + */ + private TextView positiveBn; + private TextView negtiveBn; + /** + * 按钮之间的分割线 + */ +// private View columnLineView; + + private Context mContext; + + public DeleWifiDialog(Context context) { + super(context, R.style.CustomDialog); + this.mContext = context; + } + + /** + * 都是内容数据 + */ + private String message; + private String title; + private String positive; + private int imageResId = -1; + private boolean showPasswd = false; + + /** + * 底部是否只有一个按钮 + */ + private boolean isSingle = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_delete_wifi); + //按空白处不能取消动画 + setCanceledOnTouchOutside(false); + //初始化界面控件 + initView(); + //初始化界面数据 + refreshView(); + //初始化界面控件的事件 + initEvent(); + } + + /** + * 初始化界面的确定和取消监听器 + */ + private void initEvent() { + //设置确定按钮被点击后,向外界提供监听 + positiveBn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onClickBottomListener != null) { + onClickBottomListener.onPositiveClick(); + } + } + }); + negtiveBn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dismiss(); + } + }); + } + + /** + * 初始化界面控件的显示数据 + */ + private void refreshView() { + //如果用户自定了title和message + if (!TextUtils.isEmpty(title)) { + titleTv.setText(title); + titleTv.setVisibility(View.VISIBLE); + } else { + titleTv.setVisibility(View.GONE); + } + if (!TextUtils.isEmpty(message)) { + messageTv.setText(message); + } + //如果设置按钮的文字 + if (!TextUtils.isEmpty(positive)) { + positiveBn.setText(positive); + } else { + positiveBn.setText("确定"); + } + negtiveBn.setText("取消"); + + if (imageResId != -1) { + imageIv.setImageResource(imageResId); + imageIv.setVisibility(View.VISIBLE); + } else { + imageIv.setVisibility(View.GONE); + } + /** + * 只显示一个按钮的时候隐藏取消按钮,回掉只执行确定的事件 + */ +// if (isSingle) { +//// columnLineView.setVisibility(View.GONE); +// negtiveBn.setVisibility(View.GONE); +// } else { +// negtiveBn.setVisibility(View.VISIBLE); +//// columnLineView.setVisibility(View.VISIBLE); +// } + } + + @Override + public void show() { + super.show(); + refreshView(); + } + + /** + * 初始化界面控件 + */ + private void initView() { + positiveBn = findViewById(R.id.positive); + negtiveBn = findViewById(R.id.negtive); + titleTv = findViewById(R.id.title); + messageTv = findViewById(R.id.message); + imageIv = findViewById(R.id.image); +// columnLineView = findViewById(R.id.column_line); + showKeyboard(); + } + + public void showKeyboard() { + if (messageTv != null) { + //设置可获得焦点 + messageTv.setFocusable(true); + messageTv.setFocusableInTouchMode(true); + //请求获得焦点 + messageTv.requestFocus(); + //调用系统输入法 + InputMethodManager inputManager = (InputMethodManager) messageTv + .getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + inputManager.showSoftInput(messageTv, 0); + } + } + + /** + * 设置确定取消按钮的回调 + */ + private OnClickBottomListener onClickBottomListener; + + public void setOnClickBottomListener(OnClickBottomListener onClickBottomListener) { + this.onClickBottomListener = onClickBottomListener; + } + + public interface OnClickBottomListener { + /** + * 点击确定按钮事件 + */ + void onPositiveClick(); + } + + public String getMessage() { + return message; + } + + public DeleWifiDialog setMessage(String message) { + this.message = message; + return this; + } + + public String getTitle() { + return title; + } + + public DeleWifiDialog setTitle(String title) { + this.title = title; + return this; + } + + public String getPositive() { + return positive; + } + + public DeleWifiDialog setPositive(String positive) { + this.positive = positive; + return this; + } + + public int getImageResId() { + return imageResId; + } + + public boolean isSingle() { + return isSingle; + } + + public DeleWifiDialog setSingle(boolean single) { + isSingle = single; + return this; + } + + public DeleWifiDialog setImageResId(int imageResId) { + this.imageResId = imageResId; + return this; + } + + public String getPassword() { + String passwd = messageTv.getText().toString(); + return passwd; + } + + @Override + public void dismiss() { + super.dismiss(); + } +} diff --git a/app/src/main/java/com/uiuios/aios/dialog/DeleteDialog.java b/app/src/main/java/com/uiuios/aios/dialog/DeleteDialog.java new file mode 100644 index 0000000..24a9c4c --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/dialog/DeleteDialog.java @@ -0,0 +1,251 @@ +package com.uiuios.aios.dialog; + + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import com.uiuios.aios.R; + + +/** + * description:自定义dialog + */ + +public class DeleteDialog extends AlertDialog { + /** + * 显示的图片 + */ + private ImageView imageIv; + + /** + * 显示的标题 + */ + private TextView titleTv; + + /** + * 显示的消息 + */ + private TextView messageTv; + + /** + * 确认和取消按钮 + */ + private TextView positiveBn; + private TextView negtiveBn; + + /** + * 按钮之间的分割线 + */ +// private View columnLineView; + + private Context mContext; + + public DeleteDialog(Context context) { + super(context, R.style.CustomDialog); + this.mContext = context; + } + + /** + * 都是内容数据 + */ + private String message; + private String title; + private String positive, negtive; + private int imageResId = -1; + + /** + * 底部是否只有一个按钮 + */ + private boolean isSingle = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_delete); + //按空白处不能取消动画 + setCanceledOnTouchOutside(false); + //初始化界面控件 + initView(); + //初始化界面数据 + refreshView(); + //初始化界面控件的事件 + initEvent(); + } + + /** + * 初始化界面的确定和取消监听器 + */ + private void initEvent() { + //设置确定按钮被点击后,向外界提供监听 + positiveBn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onClickBottomListener != null) { + onClickBottomListener.onPositiveClick(); + } + } + }); + //设置取消按钮被点击后,向外界提供监听 + negtiveBn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onClickBottomListener != null) { + onClickBottomListener.onNegtiveClick(); + } + } + }); + } + + /** + * 初始化界面控件的显示数据 + */ + private void refreshView() { + //如果用户自定了title和message + if (!TextUtils.isEmpty(title)) { + titleTv.setText(title); + titleTv.setVisibility(View.VISIBLE); + } else { + titleTv.setVisibility(View.GONE); + } + if (!TextUtils.isEmpty(message)) { + messageTv.setText(message); + } + //如果设置按钮的文字 + if (!TextUtils.isEmpty(positive)) { + positiveBn.setText(positive); + } else { + positiveBn.setText("确定"); + } + if (!TextUtils.isEmpty(negtive)) { + negtiveBn.setText(negtive); + } else { + negtiveBn.setText("取消"); + } + + if (imageResId != -1) { + imageIv.setImageResource(imageResId); + imageIv.setVisibility(View.VISIBLE); + } else { + imageIv.setVisibility(View.GONE); + } + /** + * 只显示一个按钮的时候隐藏取消按钮,回掉只执行确定的事件 + */ +// if (isSingle) { +//// columnLineView.setVisibility(View.GONE); +// negtiveBn.setVisibility(View.GONE); +// } else { +// negtiveBn.setVisibility(View.VISIBLE); +//// columnLineView.setVisibility(View.VISIBLE); +// } + } + + @Override + public void show() { + super.show(); + refreshView(); + } + + /** + * 初始化界面控件 + */ + private void initView() { + negtiveBn = findViewById(R.id.negtive); + positiveBn = findViewById(R.id.positive); + titleTv = findViewById(R.id.title); + messageTv = findViewById(R.id.message); + imageIv = findViewById(R.id.image); +// columnLineView = findViewById(R.id.column_line); + } + + /** + * 设置确定取消按钮的回调 + */ + private OnClickBottomListener onClickBottomListener; + + public void setOnClickBottomListener(OnClickBottomListener onClickBottomListener) { + this.onClickBottomListener = onClickBottomListener; + } + + public interface OnClickBottomListener { + /** + * 点击确定按钮事件 + */ + void onPositiveClick(); + + /** + * 点击取消按钮事件 + */ + void onNegtiveClick(); + } + + public String getMessage() { + return message; + } + + public DeleteDialog setMessage(String message) { + this.message = message; + return this; + } + + public String getTitle() { + return title; + } + + public DeleteDialog setTitle(String title) { + this.title = title; + return this; + } + + public String getPositive() { + return positive; + } + + public DeleteDialog setPositive(String positive) { + this.positive = positive; + return this; + } + + public String getNegtive() { + return negtive; + } + + public DeleteDialog setNegtive(String negtive) { + this.negtive = negtive; + return this; + } + + public DeleteDialog setNegtiveText(String negtive) { + negtiveBn.setText(negtive); + return this; + } + + public int getImageResId() { + return imageResId; + } + + public boolean isSingle() { + return isSingle; + } + + public DeleteDialog setSingle(boolean single) { + isSingle = single; + return this; + } + + public DeleteDialog setImageResId(int imageResId) { + this.imageResId = imageResId; + return this; + } + + @Override + public void dismiss() { + super.dismiss(); + } +} diff --git a/app/src/main/java/com/uiuios/aios/dialog/WifiDialog.java b/app/src/main/java/com/uiuios/aios/dialog/WifiDialog.java new file mode 100644 index 0000000..658ebc8 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/dialog/WifiDialog.java @@ -0,0 +1,265 @@ +package com.uiuios.aios.dialog; + + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.text.method.HideReturnsTransformationMethod; +import android.text.method.PasswordTransformationMethod; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import com.uiuios.aios.R; + + +/** + * description:自定义dialog + */ + +public class WifiDialog extends AlertDialog { + /** + * 显示的图片 + */ + private ImageView imageIv; + private ImageView iv_show; + private ImageView iv_close; + + /** + * 显示的标题 + */ + private TextView titleTv; + + /** + * 显示的消息 + */ + private EditText messageTv; + + /** + * 确认和取消按钮 + */ + private TextView positiveBn; + + /** + * 按钮之间的分割线 + */ +// private View columnLineView; + + private Context mContext; + + public WifiDialog(Context context) { + super(context, R.style.CustomDialog); + this.mContext = context; + } + + /** + * 都是内容数据 + */ + private String message; + private String title; + private String positive; + private int imageResId = -1; + private boolean showPasswd = false; + + /** + * 底部是否只有一个按钮 + */ + private boolean isSingle = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_wifi); + //按空白处不能取消动画 + setCanceledOnTouchOutside(false); + //初始化界面控件 + initView(); + //初始化界面数据 + refreshView(); + //初始化界面控件的事件 + initEvent(); + } + + /** + * 初始化界面的确定和取消监听器 + */ + private void initEvent() { + //设置确定按钮被点击后,向外界提供监听 + positiveBn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onClickBottomListener != null) { + onClickBottomListener.onPositiveClick(); + } + } + }); + iv_show.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (showPasswd) { + iv_show.setImageDrawable(mContext.getDrawable(R.drawable.icon_passwd_show)); + messageTv.setTransformationMethod(PasswordTransformationMethod.getInstance()); + } else { + iv_show.setImageDrawable(mContext.getDrawable(R.drawable.icon_passwd_hide)); + messageTv.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); + } + showPasswd = !showPasswd; + } + }); + iv_close.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dismiss(); + } + }); + } + + /** + * 初始化界面控件的显示数据 + */ + private void refreshView() { + //如果用户自定了title和message + if (!TextUtils.isEmpty(title)) { + titleTv.setText(title); + titleTv.setVisibility(View.VISIBLE); + } else { + titleTv.setVisibility(View.GONE); + } + if (!TextUtils.isEmpty(message)) { + messageTv.setText(message); + } + //如果设置按钮的文字 + if (!TextUtils.isEmpty(positive)) { + positiveBn.setText(positive); + } else { + positiveBn.setText("确定"); + } + + if (imageResId != -1) { + imageIv.setImageResource(imageResId); + imageIv.setVisibility(View.VISIBLE); + } else { + imageIv.setVisibility(View.GONE); + } + /** + * 只显示一个按钮的时候隐藏取消按钮,回掉只执行确定的事件 + */ +// if (isSingle) { +//// columnLineView.setVisibility(View.GONE); +// negtiveBn.setVisibility(View.GONE); +// } else { +// negtiveBn.setVisibility(View.VISIBLE); +//// columnLineView.setVisibility(View.VISIBLE); +// } + } + + @Override + public void show() { + super.show(); + refreshView(); + } + + /** + * 初始化界面控件 + */ + private void initView() { + positiveBn = findViewById(R.id.positive); + titleTv = findViewById(R.id.title); + messageTv = findViewById(R.id.message); + imageIv = findViewById(R.id.image); + iv_show = findViewById(R.id.iv_show); + iv_close = findViewById(R.id.iv_close); + +// columnLineView = findViewById(R.id.column_line); + showKeyboard(); + } + + public void showKeyboard() { + if (messageTv != null) { + //设置可获得焦点 + messageTv.setFocusable(true); + messageTv.setFocusableInTouchMode(true); + //请求获得焦点 + messageTv.requestFocus(); + //调用系统输入法 + InputMethodManager inputManager = (InputMethodManager) messageTv + .getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + inputManager.showSoftInput(messageTv, 0); + } + } + + /** + * 设置确定取消按钮的回调 + */ + private OnClickBottomListener onClickBottomListener; + + public void setOnClickBottomListener(OnClickBottomListener onClickBottomListener) { + this.onClickBottomListener = onClickBottomListener; + } + + public interface OnClickBottomListener { + /** + * 点击确定按钮事件 + */ + void onPositiveClick(); + } + + public String getMessage() { + return message; + } + + public WifiDialog setMessage(String message) { + this.message = message; + return this; + } + + public String getTitle() { + return title; + } + + public WifiDialog setTitle(String title) { + this.title = title; + return this; + } + + public String getPositive() { + return positive; + } + + public WifiDialog setPositive(String positive) { + this.positive = positive; + return this; + } + + public int getImageResId() { + return imageResId; + } + + public boolean isSingle() { + return isSingle; + } + + public WifiDialog setSingle(boolean single) { + isSingle = single; + return this; + } + + public WifiDialog setImageResId(int imageResId) { + this.imageResId = imageResId; + return this; + } + + public String getPassword() { + String passwd = messageTv.getText().toString(); + return passwd; + } + + @Override + public void dismiss() { + super.dismiss(); + } +} diff --git a/app/src/main/java/com/uiuios/aios/fragment/AppListFragment.java b/app/src/main/java/com/uiuios/aios/fragment/AppListFragment.java index b2a8939..d968b23 100644 --- a/app/src/main/java/com/uiuios/aios/fragment/AppListFragment.java +++ b/app/src/main/java/com/uiuios/aios/fragment/AppListFragment.java @@ -23,12 +23,12 @@ import com.trello.rxlifecycle4.RxLifecycle; import com.trello.rxlifecycle4.android.FragmentEvent; import com.uiuios.aios.R; import com.uiuios.aios.activity.DailyAppActivity; -import com.uiuios.aios.activity.code.FamilySpaceActivity; import com.uiuios.aios.base.BaseFragment; import com.uiuios.aios.bean.BaseResponse; import com.uiuios.aios.bean.DesktopIcon; import com.uiuios.aios.config.CommonConfig; import com.uiuios.aios.dialog.CustomDialog; +import com.uiuios.aios.dialog.DailyAppDialog; import com.uiuios.aios.manager.AppStatusManager; import com.uiuios.aios.network.NetInterfaceManager; import com.uiuios.aios.service.NotificationService; @@ -169,6 +169,7 @@ public class AppListFragment extends BaseFragment { iv.setImageDrawable(desktopIcon.getIcon()); } else { iv.setImageDrawable(getActivity().getResources().getDrawable(resID)); + desktopIcon.setIcon(mContext.getResources().getDrawable(resID)); } } else { iv.setImageBitmap(BitmapUtils.getIconBitmap(rootView.getContext(), desktopIcon.getIcon())); @@ -253,9 +254,10 @@ public class AppListFragment extends BaseFragment { switch (pkg) { case "aios.exit": case "com.uiuios.sn": + case "aios.daily.app": break; default: - showHinDialog(pkg, desktopIcon.getLable()); + showHideDialog(desktopIcon); } } }); @@ -266,23 +268,25 @@ public class AppListFragment extends BaseFragment { .compose(RxLifecycle.bindUntilEvent(lifecycleSubject, FragmentEvent.DESTROY)) .subscribe(new Observer() { @Override - public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) { + public void onSubscribe(@NonNull Disposable d) { Log.e("updateAppDisableStatus", "onSubscribe: "); } @Override - public void onNext(@io.reactivex.rxjava3.annotations.NonNull BaseResponse baseResponse) { + public void onNext(@NonNull BaseResponse baseResponse) { Log.e("updateAppDisableStatus", "onNext: " + baseResponse); if (baseResponse.code == 200) { - ApkUtils.disableApp(mContext, pkg); +// ApkUtils.disableApp(mContext, pkg); + AppStatusManager.getInstance().addHidedApp(pkg); } else { ToastUtil.show("隐藏失败,检查网络连接"); } } @Override - public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) { + public void onError(@NonNull Throwable e) { Log.e("updateAppDisableStatus", "onError: "); + ToastUtil.show("隐藏失败,检查网络连接"); onComplete(); } @@ -293,23 +297,26 @@ public class AppListFragment extends BaseFragment { }); } - private void showHinDialog(String pkg, String label) { - CustomDialog customDialog = new CustomDialog(mContext); - customDialog.setTitle("隐藏应用"); - customDialog.setMessage("是否要隐藏:" + label); - customDialog.setOnClickBottomListener(new CustomDialog.OnClickBottomListener() { + private void showHideDialog(DesktopIcon desktopIcon) { + String label = desktopIcon.getLable(); + String pkg = desktopIcon.getPackageName(); + DailyAppDialog dailyAppDialog = new DailyAppDialog(mContext); + dailyAppDialog.setTitle("移到日常应用"); + dailyAppDialog.setMessage(label); + dailyAppDialog.setIconImage(desktopIcon.getIcon()); + dailyAppDialog.setOnClickBottomListener(new DailyAppDialog.OnClickBottomListener() { @Override public void onPositiveClick() { updateAppDisableStatus(pkg, label); - customDialog.dismiss(); + dailyAppDialog.dismiss(); } @Override public void onNegtiveClick() { - customDialog.dismiss(); + dailyAppDialog.dismiss(); } }); - customDialog.show(); + dailyAppDialog.show(); } private void SendRunningApp(Context context) { diff --git a/app/src/main/java/com/uiuios/aios/fragment/custom/CustomFragment.java b/app/src/main/java/com/uiuios/aios/fragment/custom/CustomFragment.java index d7676e2..d637c04 100644 --- a/app/src/main/java/com/uiuios/aios/fragment/custom/CustomFragment.java +++ b/app/src/main/java/com/uiuios/aios/fragment/custom/CustomFragment.java @@ -56,11 +56,12 @@ import com.uiuios.aios.activity.alarm.AlarmClockActivity; import com.uiuios.aios.activity.code.FamilySpaceActivity; import com.uiuios.aios.activity.contact.ContactActivity; import com.uiuios.aios.activity.weather.WeatherActivity; +import com.uiuios.aios.activity.wifi.WiFiManagerActivity; import com.uiuios.aios.adapter.NotificationAdapter; import com.uiuios.aios.adapter.SOSNnmberAdapter; import com.uiuios.aios.alarm.AlarmUtils; import com.uiuios.aios.base.BaseFragment; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.alarm.AlarmClockData; import com.uiuios.aios.bean.AlarmItem; import com.uiuios.aios.bean.Contact; import com.uiuios.aios.bean.HealthCode; @@ -567,8 +568,10 @@ public class CustomFragment extends BaseFragment implements CustomContact.Custom cl_wifi.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS); - startActivity(intent); +// Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS); +// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); +// startActivity(intent); + startActivity(new Intent(mContext, WiFiManagerActivity.class)); } }); cl_activation.setOnClickListener(new View.OnClickListener() { @@ -603,7 +606,6 @@ public class CustomFragment extends BaseFragment implements CustomContact.Custom } else { // tv_name.setText("未设置"); } - } private void showPassword() { @@ -832,24 +834,25 @@ public class CustomFragment extends BaseFragment implements CustomContact.Custom } private void getAlarm() { - NetInterfaceManager.getInstance().getAlarmClock(new NetInterfaceManager.AlarmClockCallback() { - @Override - public void setAlarmClock(List alarmClockList) { - startActivity(new Intent(mContext, AlarmClockActivity.class)); - } - - @Override - public void setAlarmClockEmpty() { - showNoData("温馨提示", "请在小程序上设置爱心闹钟"); - rv_noti.setVisibility(View.GONE); - iv_note_nodata.setVisibility(View.VISIBLE); - } - - @Override - public void onError() { - - } - }); + startActivity(new Intent(mContext, AlarmClockActivity.class)); +// NetInterfaceManager.getInstance().getAlarmClock(new NetInterfaceManager.AlarmClockCallback() { +// @Override +// public void setAlarmClock(List alarmClockList) { +// startActivity(new Intent(mContext, AlarmClockActivity.class)); +// } +// +// @Override +// public void setAlarmClockEmpty() { +// showNoData("温馨提示", "请在小程序上设置爱心闹钟"); +// rv_noti.setVisibility(View.GONE); +// iv_note_nodata.setVisibility(View.VISIBLE); +// } +// +// @Override +// public void onError() { +// +// } +// }); } private void getAlarmCache() { diff --git a/app/src/main/java/com/uiuios/aios/gson/GsonUtils.java b/app/src/main/java/com/uiuios/aios/gson/GsonUtils.java new file mode 100644 index 0000000..ea86f97 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/gson/GsonUtils.java @@ -0,0 +1,144 @@ +package com.uiuios.aios.gson; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; +import java.util.Objects; + + +public class GsonUtils { + //https://blog.csdn.net/zte1055889498/article/details/122400299 + + public static JsonObject getJsonObject(String jsonString) { + JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject(); + return jsonObject; + } + + private static final Gson gson; + + static { + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory()); + builder.registerTypeAdapter(Integer.class, new IntegerDefault0Adapter()); + builder.registerTypeAdapter(int.class, new IntegerDefault0Adapter()); + builder.disableHtmlEscaping(); + builder.enableComplexMapKeySerialization(); + // builder.excludeFieldsWithoutExposeAnnotation(); + builder.setDateFormat("yyyy-MM-dd HH:mm:ss"); + gson = builder.create(); + } + + public static Type makeJavaType(Type rawType, Type... typeArguments) { + return TypeToken.getParameterized(rawType, typeArguments).getType(); + } + + public static String toString(Object value) { + if (Objects.isNull(value)) { + return null; + } + if (value instanceof String) { + return (String) value; + } + return toJSONString(value); + } + + public static String toJSONString(Object value) { + return gson.toJson(value); + } + + public static String toPrettyString(Object value) { + return gson.newBuilder().setPrettyPrinting().create().toJson(value); + } + + public static JsonElement fromJavaObject(Object value) { + JsonElement result = null; + if (Objects.nonNull(value) && (value instanceof String)) { + result = parseObject((String) value); + } else { + result = gson.toJsonTree(value); + } + return result; + } + + public static JsonElement parseObject(String content) { + return JsonParser.parseString(content); + } + + public static JsonElement getJsonElement(JsonObject node, String name) { + return node.get(name); + } + + public static JsonElement getJsonElement(JsonArray node, int index) { + return node.get(index); + } + + public static T toJavaObject(JsonElement node, Class clazz) { + return gson.fromJson(node, clazz); + } + + public static T toJavaObject(JsonElement node, Type type) { + return gson.fromJson(node, type); + } + + public static T toJavaObject(JsonElement node, TypeToken typeToken) { + return toJavaObject(node, typeToken.getType()); + } + + public static List toJavaList(JsonElement node, Class clazz) { + return toJavaObject(node, makeJavaType(List.class, clazz)); + } + + public static List toJavaList(JsonElement node) { + return toJavaObject(node, new TypeToken>() { + }.getType()); + } + + public static Map toJavaMap(JsonElement node, Class clazz) { + return toJavaObject(node, makeJavaType(Map.class, String.class, clazz)); + } + + public static Map toJavaMap(JsonElement node) { + return toJavaObject(node, new TypeToken>() { + }.getType()); + } + + public static T toJavaObject(String content, Class clazz) { + JsonObject jsonObject = getJsonObject(content); + String jsonString = jsonObject.toString(); + return gson.fromJson(jsonString, clazz); + } + + public static T toJavaObject(String content, Type type) { + return gson.fromJson(content, type); + } + + public static T toJavaObject(String content, TypeToken typeToken) { + return toJavaObject(content, typeToken.getType()); + } + + public static List toJavaList(String content, Class clazz) { + return toJavaObject(content, makeJavaType(List.class, clazz)); + } + + public static List toJavaList(String content) { + return toJavaObject(content, new TypeToken>() { + }.getType()); + } + + public static Map toJavaMap(String content, Class clazz) { + return toJavaObject(content, makeJavaType(Map.class, String.class, clazz)); + } + + public static Map toJavaMap(String content) { + return toJavaObject(content, new TypeToken>() { + }.getType()); + } +} diff --git a/app/src/main/java/com/uiuios/aios/gson/IntegerDefault0Adapter.java b/app/src/main/java/com/uiuios/aios/gson/IntegerDefault0Adapter.java new file mode 100644 index 0000000..a0817c3 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/gson/IntegerDefault0Adapter.java @@ -0,0 +1,35 @@ +package com.uiuios.aios.gson; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.JsonSyntaxException; + +import java.lang.reflect.Type; + +public class IntegerDefault0Adapter implements JsonSerializer, JsonDeserializer { + @Override + public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + try { + if (json.getAsString().equals("")) { + return 0; + } + } catch (Exception ignore) { + } + try { + return json.getAsInt(); + } catch (NumberFormatException e) { + throw new JsonSyntaxException(e); + } + } + + @Override + public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/uiuios/aios/gson/NullStringToEmptyAdapterFactory.java b/app/src/main/java/com/uiuios/aios/gson/NullStringToEmptyAdapterFactory.java new file mode 100644 index 0000000..5d46ae9 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/gson/NullStringToEmptyAdapterFactory.java @@ -0,0 +1,45 @@ +package com.uiuios.aios.gson; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; + +public class NullStringToEmptyAdapterFactory implements TypeAdapterFactory { + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + + Class rawType = (Class) type.getRawType(); + if (rawType != String.class) { + return null; + } + return (TypeAdapter) new StringAdapter(); + } + + public static class StringAdapter extends TypeAdapter { + @Override + public String read(JsonReader reader) throws IOException { + if (reader.peek() == JsonToken.NULL) { + reader.nextNull(); + return ""; + } + return reader.nextString(); + } + + @Override + public void write(JsonWriter writer, String value) throws IOException { + if (value == null) { + writer.nullValue(); + return; + } + writer.value(value); + } + } + +} + diff --git a/app/src/main/java/com/uiuios/aios/manager/AppStatusManager.java b/app/src/main/java/com/uiuios/aios/manager/AppStatusManager.java index f978c21..75813ad 100644 --- a/app/src/main/java/com/uiuios/aios/manager/AppStatusManager.java +++ b/app/src/main/java/com/uiuios/aios/manager/AppStatusManager.java @@ -95,7 +95,7 @@ public class AppStatusManager { int i = IconUtils.appClassNameList.indexOf(pkg); if (i != -1) { String val = IconUtils.appIconList.get(i); - int resID = mContext.getResources().getIdentifier(val, "drawable", "com.uiui.aios"); + int resID = mContext.getResources().getIdentifier(val, "drawable", "com.uiuios.aios"); if (resID != 0) { appSelectBean.setIcon(mContext.getResources().getDrawable(resID)); } diff --git a/app/src/main/java/com/uiuios/aios/network/NetInterfaceManager.java b/app/src/main/java/com/uiuios/aios/network/NetInterfaceManager.java index a7cd82f..66e7f6d 100644 --- a/app/src/main/java/com/uiuios/aios/network/NetInterfaceManager.java +++ b/app/src/main/java/com/uiuios/aios/network/NetInterfaceManager.java @@ -12,7 +12,8 @@ import com.trello.rxlifecycle4.android.ActivityEvent; import com.trello.rxlifecycle4.android.FragmentEvent; import com.uiuios.aios.alarm.AlarmUtils; import com.uiuios.aios.bean.ActivityBean; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.alarm.AlarmClockData; +import com.uiuios.aios.bean.AlarmClockId; import com.uiuios.aios.bean.ArticleInfo; import com.uiuios.aios.bean.BaseResponse; import com.uiuios.aios.bean.Contact; @@ -26,10 +27,15 @@ import com.uiuios.aios.bean.UserAvatarInfo; import com.uiuios.aios.bean.UserId; import com.uiuios.aios.config.CommonConfig; import com.uiuios.aios.disklrucache.CacheHelper; +import com.uiuios.aios.gson.GsonUtils; import com.uiuios.aios.manager.ConnectManager; import com.uiuios.aios.manager.ConnectMode; import com.uiuios.aios.network.api.ActivityListApi; +import com.uiuios.aios.network.api.AlarmClockAddApi; import com.uiuios.aios.network.api.AlarmClockApi; +import com.uiuios.aios.network.api.AlarmClockDeleteApi; +import com.uiuios.aios.network.api.AlarmClockEditApi; +import com.uiuios.aios.network.api.AlarmClockQueryApi; import com.uiuios.aios.network.api.AppUsageRecordApi; import com.uiuios.aios.network.api.ArticleListApi; import com.uiuios.aios.network.api.DemandListApi; @@ -50,7 +56,6 @@ import com.uiuios.aios.network.api.UpdateAppIconApi; import com.uiuios.aios.network.api.UpdateDesktopApi; import com.uiuios.aios.network.api.UserInfoControl; import com.uiuios.aios.network.interceptor.RepeatRequestInterceptor; -import com.uiuios.aios.utils.GsonUtils; import com.uiuios.aios.utils.Utils; import java.io.File; @@ -182,14 +187,6 @@ public class NetInterfaceManager { .observeOn(AndroidSchedulers.mainThread()); } - public Observable>> getAlarmClockObservable() { - return mRetrofit - .create(AlarmClockApi.class) - .getAlarmClockApiApi(Utils.getSerial()) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()); - } - public Observable getRunningAppObservable(String json) { return mRetrofit.create(RunNewApp.class) .sendRunningInfo(Utils.getSerial(), json) @@ -274,6 +271,46 @@ public class NetInterfaceManager { .observeOn(AndroidSchedulers.mainThread()); } + /* + *闹钟相关 + */ + + public Observable>> getAlarmClockObservable() { + return mRetrofit + .create(AlarmClockApi.class) + .getAlarmClockApiApi(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable> getAlarmClockAddObservable(Map params, MultipartBody.Part body) { + return mRetrofit.create(AlarmClockAddApi.class) + .addAlarmClock(params, body) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable getAlarmClockEditObservable(Map params, MultipartBody.Part body) { + return mRetrofit.create(AlarmClockEditApi.class) + .editAlarmClock(params, body) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable> getAlarmClockByIdObservable(int id) { + return mRetrofit.create(AlarmClockQueryApi.class) + .getAlarmClockById(Utils.getSerial(), id) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable deleteAlarmClockObservable(int id) { + return mRetrofit.create(AlarmClockDeleteApi.class) + .alarmClockDelete(Utils.getSerial(), id) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + public interface onCompleteCallback { void onComplete(); } @@ -321,7 +358,7 @@ public class NetInterfaceManager { Log.e("getUserID", "onNext: " + userIdBaseResponse); if (userIdBaseResponse.code == 200) { UserId userId = userIdBaseResponse.data; - mCacheHelper.put(UrlAddress.GET_USER_ID, GsonUtils.toJsonString(userId)); + mCacheHelper.put(UrlAddress.GET_USER_ID, GsonUtils.toJSONString(userId)); mMMKV.encode("USER_ID", userId.getUser_id()); } else { mCacheHelper.put(UrlAddress.GET_USER_ID, -1); @@ -421,7 +458,7 @@ public class NetInterfaceManager { mCacheHelper.put(UrlAddress.GET_ACTIVITY_LIST, ""); if (callback != null) callback.noData(); } else { - mCacheHelper.put(UrlAddress.GET_ACTIVITY_LIST, GsonUtils.toJsonString(activityBeans)); + mCacheHelper.put(UrlAddress.GET_ACTIVITY_LIST, GsonUtils.toJSONString(activityBeans)); if (callback != null) callback.setActivitiesList(activityBeans); } } else { @@ -532,7 +569,7 @@ public class NetInterfaceManager { mCacheHelper.put(UrlAddress.GET_DEMAND_LIST, ""); if (callback != null) callback.noData(); } else { - mCacheHelper.put(UrlAddress.GET_DEMAND_LIST, GsonUtils.toJsonString(demandBeans)); + mCacheHelper.put(UrlAddress.GET_DEMAND_LIST, GsonUtils.toJSONString(demandBeans)); if (callback != null) callback.setDemandList(demandBeans); } } else { @@ -650,7 +687,7 @@ public class NetInterfaceManager { Log.e("getHealthCode", "onNext: " + listBaseResponse); if (listBaseResponse.code == 200) { List healthCodeList = listBaseResponse.data; - mCacheHelper.put(UrlAddress.GET_HEALTH_CODE, GsonUtils.toJsonString(healthCodeList)); + mCacheHelper.put(UrlAddress.GET_HEALTH_CODE, GsonUtils.toJSONString(healthCodeList)); callback.setHealthCode(healthCodeList); } else { mCacheHelper.put(UrlAddress.GET_HEALTH_CODE, ""); @@ -703,23 +740,23 @@ public class NetInterfaceManager { // } } - public void getAlarmClockCache(BehaviorSubject lifecycle, AlarmClockCallback callback) { - String jsonString = mCacheHelper.getAsString(UrlAddress.GET_ALARM_CLOCK); - //为 "" 是已经请求成功的 - if (jsonString == null) { - getAlarmClock(lifecycle, callback); - } else { - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - List list = gson.fromJson(jsonString, type); - if (list == null || list.size() == 0) { - callback.setAlarmClockEmpty(); - } else { - callback.setAlarmClock(list); - } - } - } +// public void getAlarmClockCache(BehaviorSubject lifecycle, AlarmClockCallback callback) { +// String jsonString = mCacheHelper.getAsString(UrlAddress.GET_ALARM_CLOCK); +// //为 "" 是已经请求成功的 +// if (jsonString == null) { +// getAlarmClock(lifecycle, callback); +// } else { +// Gson gson = new Gson(); +// Type type = new TypeToken>() { +// }.getType(); +// List list = gson.fromJson(jsonString, type); +// if (list == null || list.size() == 0) { +// callback.setAlarmClockEmpty(); +// } else { +// callback.setAlarmClock(list); +// } +// } +// } public void getAlarmClock(BehaviorSubject lifecycle, AlarmClockCallback callback) { getAlarmClockObservable() @@ -751,34 +788,34 @@ public class NetInterfaceManager { List alarmClockData = listBaseResponse.data; if (alarmClockData != null && alarmClockData.size() != 0) { AlarmUtils.getInstance().setAlarmClockData(alarmClockData); - if (callback != null) callback.setAlarmClock(alarmClockData); + mMMKV.encode(UrlAddress.GET_ALARM_CLOCK, GsonUtils.toJSONString(alarmClockData)); + +// if (callback != null) { +// callback.setAlarmClock(alarmClockData); +// } } else { AlarmUtils.getInstance().deleteAllAlarmClock(); AlarmUtils.getInstance().setAlarmClockData(null); - if (callback != null) callback.setAlarmClockEmpty(); + mMMKV.encode(UrlAddress.GET_ALARM_CLOCK, ""); + +// if (callback != null) { +// callback.setAlarmClockEmpty(); +// } } - mCacheHelper.put(UrlAddress.GET_ALARM_CLOCK, GsonUtils.toJsonString(alarmClockData)); } else { AlarmUtils.getInstance().deleteAllAlarmClock(); AlarmUtils.getInstance().setAlarmClockData(null); - mCacheHelper.put(UrlAddress.GET_ALARM_CLOCK, ""); - if (callback != null) callback.setAlarmClockEmpty(); + mMMKV.encode(UrlAddress.GET_ALARM_CLOCK, ""); + +// if (callback != null) { +// callback.setAlarmClockEmpty(); +// } } } @Override public void onError(@NonNull Throwable e) { Log.e("getAlarmClockObserver", "onError: " + e.getMessage()); - String jsonString = mCacheHelper.getAsString(UrlAddress.GET_ALARM_CLOCK); - Gson gson = new Gson(); - Type type = new TypeToken>() { - }.getType(); - List list = gson.fromJson(jsonString, type); - if (list == null || list.size() == 0) { - if (callback != null) callback.setAlarmClockEmpty(); - } else { - if (callback != null) callback.setAlarmClock(list); - } if (callback != null) callback.onError(); onComplete(); } @@ -786,6 +823,13 @@ public class NetInterfaceManager { @Override public void onComplete() { Log.e("getAlarmClockObserver", "onComplete: "); + List list = AlarmUtils.getInstance().getOldData(); + if (list == null || list.size() == 0) { + if (callback != null) callback.setAlarmClockEmpty(); + } else { + List filter = list.stream().filter(alarmClockData -> !alarmClockData.isDeleted()).collect(Collectors.toList()); + if (callback != null) callback.setAlarmClock(filter); + } } }; } @@ -896,7 +940,7 @@ public class NetInterfaceManager { if (callback != null) callback.setEmpty(); } else { List emergencyContact = setting_sos.stream().filter(contact -> contact.getIs_urgent() == 1).collect(Collectors.toList()); - mCacheHelper.put(UrlAddress.GET_SETTINGS, GsonUtils.toJsonString(setting_sos)); + mCacheHelper.put(UrlAddress.GET_SETTINGS, GsonUtils.toJSONString(setting_sos)); if (callback != null) { callback.setContact(setting_sos); callback.setEmergencyContact(emergencyContact); @@ -998,7 +1042,7 @@ public class NetInterfaceManager { mCacheHelper.put(UrlAddress.GET_MAIL_LIST, ""); if (callback != null) callback.setEmpty(); } else { - mCacheHelper.put(UrlAddress.GET_MAIL_LIST, GsonUtils.toJsonString(contactList)); + mCacheHelper.put(UrlAddress.GET_MAIL_LIST, GsonUtils.toJSONString(contactList)); List emergencyContact = contactList.stream().filter(contact -> contact.getIs_urgent() == 1).collect(Collectors.toList()); if (callback != null) { callback.setContact(contactList); diff --git a/app/src/main/java/com/uiuios/aios/network/api/AlarmClockAddApi.java b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockAddApi.java new file mode 100644 index 0000000..18d0fe1 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockAddApi.java @@ -0,0 +1,23 @@ +package com.uiuios.aios.network.api; + +import com.uiuios.aios.bean.AlarmClockId; +import com.uiuios.aios.bean.BaseResponse; +import com.uiuios.aios.network.UrlAddress; + +import java.util.Map; + +import io.reactivex.rxjava3.core.Observable; +import okhttp3.MultipartBody; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.Part; +import retrofit2.http.QueryMap; + +public interface AlarmClockAddApi { + @Multipart + @POST(UrlAddress.ALARM_CLOCK_ADD) + Observable> addAlarmClock( + @QueryMap Map params, + @Part MultipartBody.Part body + ); +} diff --git a/app/src/main/java/com/uiuios/aios/network/api/AlarmClockApi.java b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockApi.java index 0604529..1a4e68b 100644 --- a/app/src/main/java/com/uiuios/aios/network/api/AlarmClockApi.java +++ b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockApi.java @@ -1,6 +1,6 @@ package com.uiuios.aios.network.api; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.alarm.AlarmClockData; import com.uiuios.aios.bean.BaseResponse; import com.uiuios.aios.network.UrlAddress; diff --git a/app/src/main/java/com/uiuios/aios/network/api/AlarmClockDeleteApi.java b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockDeleteApi.java new file mode 100644 index 0000000..130028b --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockDeleteApi.java @@ -0,0 +1,18 @@ +package com.uiuios.aios.network.api; + +import com.uiuios.aios.bean.BaseResponse; +import com.uiuios.aios.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface AlarmClockDeleteApi { + @FormUrlEncoded + @POST(UrlAddress.ALARM_CLOCK_DELETE) + Observable alarmClockDelete( + @Field("sn") String sn, + @Field("id") int id + ); +} diff --git a/app/src/main/java/com/uiuios/aios/network/api/AlarmClockEditApi.java b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockEditApi.java new file mode 100644 index 0000000..dfe2aa7 --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockEditApi.java @@ -0,0 +1,22 @@ +package com.uiuios.aios.network.api; + +import com.uiuios.aios.bean.BaseResponse; +import com.uiuios.aios.network.UrlAddress; + +import java.util.Map; + +import io.reactivex.rxjava3.core.Observable; +import okhttp3.MultipartBody; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.Part; +import retrofit2.http.QueryMap; + +public interface AlarmClockEditApi { + @Multipart + @POST(UrlAddress.ALARM_CLOCK_EDIT) + Observable editAlarmClock( + @QueryMap Map params, + @Part MultipartBody.Part body + ); +} diff --git a/app/src/main/java/com/uiuios/aios/network/api/AlarmClockQueryApi.java b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockQueryApi.java new file mode 100644 index 0000000..59de7ac --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/network/api/AlarmClockQueryApi.java @@ -0,0 +1,17 @@ +package com.uiuios.aios.network.api; + +import com.uiuios.aios.alarm.AlarmClockData; +import com.uiuios.aios.bean.BaseResponse; +import com.uiuios.aios.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface AlarmClockQueryApi { + @GET(UrlAddress.ALARM_CLOCK_BY_ID) + Observable> getAlarmClockById( + @Query("sn") String sn, + @Query("id") int id + ); +} diff --git a/app/src/main/java/com/uiuios/aios/service/main/MainSContact.java b/app/src/main/java/com/uiuios/aios/service/main/MainSContact.java index f5e44a3..55573e6 100644 --- a/app/src/main/java/com/uiuios/aios/service/main/MainSContact.java +++ b/app/src/main/java/com/uiuios/aios/service/main/MainSContact.java @@ -2,17 +2,21 @@ package com.uiuios.aios.service.main; import com.uiuios.aios.base.BasePresenter; import com.uiuios.aios.base.BaseView; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.alarm.AlarmClockData; import java.util.List; public class MainSContact { public interface Presenter extends BasePresenter { + void addAlarmClock(); + void deleteAlarmClock(); //设置所有信息 void getAlarmClock(); } public interface MainSView extends BaseView { + void addAlarmClockFinish(); + void deleteAlarmClockFinish(); //获取所有信息 void setAlarmClock(List dataList); } diff --git a/app/src/main/java/com/uiuios/aios/service/main/MainSPresenter.java b/app/src/main/java/com/uiuios/aios/service/main/MainSPresenter.java index 3850d65..1d5ce35 100644 --- a/app/src/main/java/com/uiuios/aios/service/main/MainSPresenter.java +++ b/app/src/main/java/com/uiuios/aios/service/main/MainSPresenter.java @@ -4,14 +4,30 @@ import android.content.Context; import android.util.Log; import com.tencent.mmkv.MMKV; +import com.trello.rxlifecycle4.RxLifecycle; import com.trello.rxlifecycle4.android.ActivityEvent; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.alarm.AlarmClockData; +import com.uiuios.aios.alarm.AlarmUtils; +import com.uiuios.aios.bean.AlarmClockId; +import com.uiuios.aios.bean.BaseResponse; import com.uiuios.aios.config.CommonConfig; import com.uiuios.aios.network.NetInterfaceManager; +import com.uiuios.aios.utils.Utils; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.subjects.BehaviorSubject; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; /** @@ -52,6 +68,207 @@ public class MainSPresenter implements MainSContact.Presenter { this.mView = null; } + private int addFinishStatu; + + @Override + public void addAlarmClock() { + List localAddAlarm = AlarmUtils.getInstance().getLocalAddAlarm(); + if (localAddAlarm.size() == 0) { + Log.e(TAG, "addAlarmClock: localAddAlarm is empty"); + mView.addAlarmClockFinish(); + } else { + addFinishStatu = 0; + for (AlarmClockData alarmClockData : localAddAlarm) { + Map params = new HashMap<>(); + params.put("sn", Utils.getSerial()); + params.put("time", alarmClockData.getTime()); + params.put("type", String.valueOf(alarmClockData.getType())); + params.put("title", alarmClockData.getTitle()); + params.put("remind_type", "0"); + params.put("is_onoff", "1"); + + File picFile = new File(alarmClockData.getFile()); + MediaType mediaType = MediaType.Companion.parse("image/png"); + RequestBody requestBody = RequestBody.Companion.create(picFile, mediaType); + MultipartBody.Part body = MultipartBody.Part.createFormData("file", picFile.getName(), requestBody); + + NetInterfaceManager.getInstance().getAlarmClockAddObservable(params, body) + .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("addAlarmClock", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse alarmClockIdBaseResponse) { + Log.e("addAlarmClock", "onNext: " + alarmClockIdBaseResponse); + if (alarmClockIdBaseResponse.code == 200) { + alarmClockData.setIs_local(false); + AlarmUtils.getInstance().updateAlarmClock(alarmClockData, alarmClockIdBaseResponse.data.getId()); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("addAlarmClock", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + addFinishStatu += 1; + Log.e("addAlarmClock", "onComplete: " + addFinishStatu); + if (addFinishStatu == localAddAlarm.size()) { + mView.addAlarmClockFinish(); + } + } + }); + } +// Observable.concat(getAddObservableList(localAddAlarm)) +// .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) +// .subscribe(new Observer>() { +// @Override +// public void onSubscribe(@NonNull Disposable d) { +// Log.e("addAlarmClock", "onSubscribe: "); +// } +// +// @Override +// public void onNext(@NonNull BaseResponse baseResponse) { +// Log.e("addAlarmClock", "onSubscribe: " + baseResponse); +// } +// +// @Override +// public void onError(@NonNull Throwable e) { +// Log.e("addAlarmClock", "onError: " + e.getMessage()); +// onComplete(); +// } +// +// @Override +// public void onComplete() { +// Log.e("addAlarmClock", "onSubscribe: "); +// } +// }); + } + } + + /** + * 创建被观察者集合 + * + * @param alarmClockDataList + * @return + */ + private List>> getAddObservableList(List alarmClockDataList) { + List>> events = new ArrayList<>(); + for (AlarmClockData alarmClockData : alarmClockDataList) { + events.add(getAddObservable(alarmClockData)); + } + return events; + } + + private Observable> getAddObservable(AlarmClockData alarmClockData) { + Map params = new HashMap<>(); + params.put("sn", Utils.getSerial()); + params.put("time", alarmClockData.getTime()); + params.put("type", String.valueOf(alarmClockData.getType())); + params.put("title", alarmClockData.getTitle()); + params.put("remind_type", "0"); + params.put("is_onoff", "1"); + + File picFile = new File(alarmClockData.getFile()); + MediaType mediaType = MediaType.Companion.parse("image/png"); + RequestBody requestBody = RequestBody.Companion.create(picFile, mediaType); + MultipartBody.Part body = MultipartBody.Part.createFormData("file", picFile.getName(), requestBody); + + return NetInterfaceManager.getInstance().getAlarmClockAddObservable(params, body); + } + + private int deleteFinishStatu; + + @Override + public void deleteAlarmClock() { + List deletedAlarm = AlarmUtils.getInstance().getDeletedAlarm(); + if (deletedAlarm.size() == 0) { + Log.e(TAG, "deleteAlarmClock: deletedAlarm is empty"); + mView.deleteAlarmClockFinish(); + } else { + deleteFinishStatu = 0; + for (AlarmClockData alarmClockData : deletedAlarm) { + NetInterfaceManager.getInstance().deleteAlarmClockObservable(alarmClockData.getId()) + .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("deleteAlarmClock", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("deleteAlarmClock", "onNext: " + baseResponse); + AlarmUtils.getInstance().deleteAlarmClock(alarmClockData.getId()); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("deleteAlarmClock", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + deleteFinishStatu += 1; + Log.e("deleteAlarmClock", "onComplete: " + deleteFinishStatu); + if (deleteFinishStatu == deletedAlarm.size()) { + mView.deleteAlarmClockFinish(); + } + } + }); + } +// Observable.concat(getDeletedObservableList(deletedAlarm)) +// .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) +// .subscribe(new Observer() { +// @Override +// public void onSubscribe(@NonNull Disposable d) { +// Log.e("deleteAlarmClock", "onSubscribe: "); +// } +// +// @Override +// public void onNext(@NonNull BaseResponse baseResponse) { +// Log.e("deleteAlarmClock", "onSubscribe: " + baseResponse); +// AlarmUtils.getInstance().deleteAlarmClock(deletedAlarm.get()); +// } +// +// @Override +// public void onError(@NonNull Throwable e) { +// Log.e("deleteAlarmClock", "onError: " + e.getMessage()); +// onComplete(); +// } +// +// @Override +// public void onComplete() { +// Log.e("deleteAlarmClock", "onSubscribe: "); +// } +// }); + } + } + + /** + * 创建被观察者集合 + * + * @param alarmClockDataList + * @return + */ + private List> getDeletedObservableList(List alarmClockDataList) { + List> events = new ArrayList<>(); + for (AlarmClockData alarmClockData : alarmClockDataList) { + events.add(getDeletedObservable(alarmClockData)); + } + return events; + } + + private Observable getDeletedObservable(AlarmClockData alarmClockData) { + return NetInterfaceManager.getInstance().deleteAlarmClockObservable(alarmClockData.getId()); + } @Override public void getAlarmClock() { diff --git a/app/src/main/java/com/uiuios/aios/service/main/MainService.java b/app/src/main/java/com/uiuios/aios/service/main/MainService.java index 9684f18..303667a 100644 --- a/app/src/main/java/com/uiuios/aios/service/main/MainService.java +++ b/app/src/main/java/com/uiuios/aios/service/main/MainService.java @@ -19,7 +19,7 @@ import com.uiuios.aios.BuildConfig; import com.uiuios.aios.activity.NoticeActivity; import com.uiuios.aios.alarm.AlarmUtils; import com.uiuios.aios.base.BaseService; -import com.uiuios.aios.bean.AlarmClockData; +import com.uiuios.aios.alarm.AlarmClockData; import com.uiuios.aios.bean.BaseResponse; import com.uiuios.aios.network.NetInterfaceManager; import com.uiuios.aios.utils.ApkUtils; @@ -51,7 +51,7 @@ import okhttp3.RequestBody; public class MainService extends BaseService implements MainSContact.MainSView, NetworkUtils.OnNetworkStatusChangedListener { private static final String TAG = MainService.class.getSimpleName(); @SuppressLint("StaticFieldLeak") - public static MainSPresenter mPresenter; + public MainSPresenter mPresenter; public MainService() { @@ -64,7 +64,9 @@ public class MainService extends BaseService implements MainSContact.MainSView, @Override public void onConnected(NetworkUtils.NetworkType networkType) { - + if (isScreenOn()) { + mPresenter.addAlarmClock(); + } } @Override @@ -87,7 +89,7 @@ public class MainService extends BaseService implements MainSContact.MainSView, mPresenter.attachView(this); mPresenter.setLifecycle(lifecycleSubject); NetworkUtils.registerNetworkStatusChangedListener(this); - mPresenter.getAlarmClock(); + mPresenter.addAlarmClock(); registerAlarmReceiver(); registerTimeReceiver(); registerLockScreenReceiver(); @@ -115,11 +117,27 @@ public class MainService extends BaseService implements MainSContact.MainSView, } } + @Override + public void addAlarmClockFinish() { + mPresenter.deleteAlarmClock(); + } + + @Override + public void deleteAlarmClockFinish() { + mPresenter.getAlarmClock(); + } + @Override public void setAlarmClock(List dataList) { } + public boolean isScreenOn() { + PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); + //true为打开,false为关闭 + return powerManager.isInteractive(); + } + public static final String ALARMWAKEUP = "ALARM_WAKEUP"; private void registerAlarmReceiver() { @@ -157,7 +175,7 @@ public class MainService extends BaseService implements MainSContact.MainSView, } public void setNextAlarm(int code) { - HashMap clockDataHashMap = AlarmUtils.getInstance().getOldData(); + HashMap clockDataHashMap = AlarmUtils.getInstance().getOldDataMap(); AlarmClockData alarmClockData = clockDataHashMap.get(code); Log.e(TAG, "setNextAlarm: " + alarmClockData); if (alarmClockData != null) { @@ -415,7 +433,7 @@ public class MainService extends BaseService implements MainSContact.MainSView, @Download.onTaskRunning protected void running(DownloadTask task) { Log.e("aria", "正在下载:" + task.getPercent() + ":" + task.getExtendField()); - ToastUtil.show("正在下载:" + task.getPercent() + "%" + "\t" + Formatter.formatFileSize(MainService.this, task.getSpeed()) + "/s"); +// ToastUtil.show("正在下载:" + task.getPercent() + "%" + "\t" + Formatter.formatFileSize(MainService.this, task.getSpeed()) + "/s"); } @Download.onTaskComplete diff --git a/app/src/main/java/com/uiuios/aios/utils/ApkUtils.java b/app/src/main/java/com/uiuios/aios/utils/ApkUtils.java index 11b471b..f77374e 100644 --- a/app/src/main/java/com/uiuios/aios/utils/ApkUtils.java +++ b/app/src/main/java/com/uiuios/aios/utils/ApkUtils.java @@ -20,6 +20,7 @@ import androidx.annotation.RequiresApi; import com.uiuios.aios.BuildConfig; import com.uiuios.aios.R; import com.uiuios.aios.bean.DesktopIcon; +import com.uiuios.aios.manager.AppStatusManager; import com.uiuios.aios.receiver.InstallResultReceiver; import java.io.File; @@ -182,6 +183,10 @@ public class ApkUtils { Log.e(TAG, "queryFilterAppInfo: disable = " + pkg); continue; } + if (AppStatusManager.getInstance().getHidedAppSet().contains(pkg)) { + Log.e(TAG, "queryFilterAppInfo: hided = " + pkg); + continue; + } if (isSystemApp(context, pkg))//通过flag排除系统应用,会将电话、短信也排除掉 { if (showPackageName.contains(pkg)) { @@ -194,9 +199,9 @@ public class ApkUtils { // resolveInfos.add(resolveInfo); // } // } else { - if (allowPackages.contains(pkg) && !excludePackageName.contains(pkg)) { - resolveInfos.add(resolveInfo); - } + if (allowPackages.contains(pkg) && !excludePackageName.contains(pkg)) { + resolveInfos.add(resolveInfo); + } // } } } diff --git a/app/src/main/java/com/uiuios/aios/utils/FileUtil.java b/app/src/main/java/com/uiuios/aios/utils/FileUtil.java index acac874..a01f4f1 100644 --- a/app/src/main/java/com/uiuios/aios/utils/FileUtil.java +++ b/app/src/main/java/com/uiuios/aios/utils/FileUtil.java @@ -2,6 +2,7 @@ package com.uiuios.aios.utils; import android.text.TextUtils; +import java.io.File; import java.util.HashSet; public class FileUtil { @@ -14,6 +15,10 @@ public class FileUtil { } } + public static boolean isLocalPath(String path) { + return path.startsWith(File.separator); + } + private static HashSet videoFormat = new HashSet() {{ this.add(".mp4"); this.add(".avi"); diff --git a/app/src/main/java/com/uiuios/aios/utils/GlideLoadUtils.java b/app/src/main/java/com/uiuios/aios/utils/GlideLoadUtils.java index 513abbd..02828be 100644 --- a/app/src/main/java/com/uiuios/aios/utils/GlideLoadUtils.java +++ b/app/src/main/java/com/uiuios/aios/utils/GlideLoadUtils.java @@ -11,6 +11,8 @@ import androidx.fragment.app.Fragment; import com.bumptech.glide.Glide; +import java.io.File; + /** * Glide 加载 简单判空封装 防止异步加载数据时调用Glide 抛出异常 * Created by Li_Xavier on 2017/6/20 0020. @@ -51,6 +53,22 @@ public class GlideLoadUtils { } } + public void glideLoad(Context context, String url, ImageView imageView) { + if (context != null) { + Glide.with(context).load(url).centerCrop().into(imageView); + } else { + Log.i(TAG, "Picture loading failed,context is null"); + } + } + + public void glideLoad(Context context, File file, ImageView imageView) { + if (context != null) { + Glide.with(context).load(file).centerCrop().into(imageView); + } else { + Log.i(TAG, "Picture loading failed,context is null"); + } + } + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public void glideLoad(Activity activity, String url, ImageView imageView, int default_image) { if (!activity.isDestroyed()) { diff --git a/app/src/main/java/com/uiuios/aios/utils/GsonUtils.java b/app/src/main/java/com/uiuios/aios/utils/GsonUtils.java deleted file mode 100644 index d71a588..0000000 --- a/app/src/main/java/com/uiuios/aios/utils/GsonUtils.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.uiuios.aios.utils; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - - -public class GsonUtils { - public static JsonObject getJsonObject(String jsonString) { - JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject(); - return jsonObject; - } - - // TODO: 2022/3/31 暂时没有实现 - public static T getJsonFromType(String jsonString, Class clazz) { - Gson gson = new Gson(); - T t = (T) gson.fromJson(jsonString, clazz); - return t; - } - - public static String toJsonString(Object o) { - return new Gson().toJson(o); - } -} diff --git a/app/src/main/java/com/uiuios/aios/utils/ScreenUtil.java b/app/src/main/java/com/uiuios/aios/utils/ScreenUtil.java new file mode 100644 index 0000000..632469d --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/utils/ScreenUtil.java @@ -0,0 +1,21 @@ +package com.uiuios.aios.utils; + +import android.content.Context; + +public class ScreenUtil { + /** + * 根据手机的分辨率从 dp 的单位 转成为 px(像素) + */ + public static int dip2px(Context context, float dpValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + } + + /** + * 根据手机的分辨率从 px(像素) 的单位 转成为 dp + */ + public static int px2dip(Context context, float pxValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (pxValue / scale + 0.5f); + } +} diff --git a/app/src/main/java/com/uiuios/aios/utils/TimeUtils.java b/app/src/main/java/com/uiuios/aios/utils/TimeUtils.java index a5bc99d..18eb897 100644 --- a/app/src/main/java/com/uiuios/aios/utils/TimeUtils.java +++ b/app/src/main/java/com/uiuios/aios/utils/TimeUtils.java @@ -26,4 +26,12 @@ public class TimeUtils { Date date = new Date(millSec); return sdf.format(date); } + + public static String secToTime(int totalSecs) { + int hours = totalSecs / 3600; + int minutes = (totalSecs % 3600) / 60; + int seconds = totalSecs % 60; + String timeString = String.format("%02d:%02d:%02d", hours, minutes, seconds); + return timeString; + } } diff --git a/app/src/main/java/com/uiuios/aios/utils/ToastUtil.java b/app/src/main/java/com/uiuios/aios/utils/ToastUtil.java index 8375104..e83dfad 100644 --- a/app/src/main/java/com/uiuios/aios/utils/ToastUtil.java +++ b/app/src/main/java/com/uiuios/aios/utils/ToastUtil.java @@ -7,6 +7,7 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.util.Log; +import android.view.Gravity; import android.widget.Toast; import com.blankj.utilcode.util.ToastUtils; @@ -41,13 +42,13 @@ public class ToastUtil { ToastUtils.make() // .setBgColor(ColorUtils.getColor(R.color.toast_color)) .setTextColor(Color.DKGRAY) -// .setGravity(Gravity.CENTER, 0, 0) + .setGravity(Gravity.CENTER, 0, 0) .setNotUseSystemToast() .show(msg); } public static void betaShow(final String msg) { - if ( BuildConfig.DEBUG) { + if (BuildConfig.DEBUG) { ToastUtils.make() // .setBgColor(ColorUtils.getColor(R.color.toast_color)) .setTextColor(Color.RED) diff --git a/app/src/main/java/com/uiuios/aios/utils/WiFiUtils.java b/app/src/main/java/com/uiuios/aios/utils/WiFiUtils.java new file mode 100644 index 0000000..832abca --- /dev/null +++ b/app/src/main/java/com/uiuios/aios/utils/WiFiUtils.java @@ -0,0 +1,225 @@ +package com.uiuios.aios.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.text.TextUtils; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author : fanhuitong + * e-mail : + * @date : 2021/10/25 10:20 + * desc : + * version: 1.0 + */ +public class WiFiUtils { + private static WiFiUtils sInstance; + private static WifiManager mWifiManager; + @SuppressLint("StaticFieldLeak") + private Context mContext; + private static String TAG = WiFiUtils.class.getSimpleName(); + + public WiFiUtils(Context context) { + this.mContext = context; + } + + public static void init(Context context) { + mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + if (sInstance == null) { + Log.e(TAG, "init: "); + sInstance = new WiFiUtils(context); + } + } + + public static WiFiUtils getInstance() { + if (sInstance == null) { + throw new IllegalStateException("You must be init WiFiUtils first"); + } + return sInstance; + } + + /** + * wifi是否打开 + * + * @return + */ + public boolean isWifiEnable() { + boolean isEnable = false; + if (mWifiManager != null) { + if (mWifiManager.isWifiEnabled()) { + isEnable = true; + } + } + return isEnable; + } + + /** + * 打开WiFi + */ + public void openWifi() { + if (mWifiManager != null && !isWifiEnable()) { + mWifiManager.setWifiEnabled(true); + } + } + + /** + * 关闭WiFi + */ + public void closeWifi() { + if (mWifiManager != null && isWifiEnable()) { + mWifiManager.setWifiEnabled(false); + } + } + + /** + * 获取WiFi列表 + * + * @return + */ + public List getWifiList() { + List resultList = new ArrayList<>(); + if (mWifiManager != null && isWifiEnable()) { + resultList.addAll(mWifiManager.getScanResults()); + } + return resultList; + } + + + /** + * 有密码连接 + * + * @param ssid + * @param pws + */ + public static void connectWifiPws(String ssid, String pws) { +// mWifiManager.disableNetwork(mWifiManager.getConnectionInfo().getNetworkId()); + mWifiManager.disconnect(); + int netId = mWifiManager.addNetwork(getWifiConfig(ssid, pws, true)); + mWifiManager.enableNetwork(netId, true); + mWifiManager.reconnect(); + } + + /** + * 无密码连接 + * + * @param ssid + */ + public void connectWifiNoPws(String ssid) { +// mWifiManager.disableNetwork(mWifiManager.getConnectionInfo().getNetworkId()); + int netId = mWifiManager.addNetwork(getWifiConfig(ssid, "", false)); + mWifiManager.enableNetwork(netId, true); + } + + /** + * wifi设置 + * + * @param ssid + * @param pws + * @param isHasPws + */ + private static WifiConfiguration getWifiConfig(String ssid, String pws, boolean isHasPws) { + WifiConfiguration config = new WifiConfiguration(); + config.allowedAuthAlgorithms.clear(); + config.allowedGroupCiphers.clear(); + config.allowedKeyManagement.clear(); + config.allowedPairwiseCiphers.clear(); + config.allowedProtocols.clear(); + config.SSID = "\"" + ssid + "\""; + + WifiConfiguration tempConfig = isExist(ssid); + if (tempConfig != null) { + mWifiManager.removeNetwork(tempConfig.networkId); + } + if (isHasPws) { + config.preSharedKey = "\"" + pws + "\""; + config.hiddenSSID = true; + config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); + config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); + config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); + config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); + config.status = WifiConfiguration.Status.ENABLED; + } else { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + } + return config; + } + + /** + * 得到配置好的网络连接 + * + * @param ssid + * @return + */ + private static WifiConfiguration isExist(String ssid) { + List configs = mWifiManager.getConfiguredNetworks(); + for (WifiConfiguration config : configs) { + if (config.SSID.equals("\"" + ssid + "\"")) { + return config; + } + } + return null; + } + + public static void addWiFiNetwork(String ssid, String passwd) { + int netId; + if (TextUtils.isEmpty(passwd)) { + netId = mWifiManager.addNetwork(getWifiConfig(ssid, "", false)); + } else { + netId = mWifiManager.addNetwork(getWifiConfig(ssid, passwd, true)); + } + mWifiManager.enableNetwork(netId, true); + } + + public static void removeWiFiNetwork(String ssid) { + WifiConfiguration tempConfig = isExist(ssid); + int networkId = tempConfig.networkId; + mWifiManager.removeNetwork(networkId); + mWifiManager.saveConfiguration(); + } + + synchronized private static boolean wifiSaved(String ssid) { + // 获取已保存wifi配置链表 + List configs = mWifiManager.getConfiguredNetworks(); + boolean saved = false; + for (WifiConfiguration configuration : configs) { + if (ssid.equals(configuration.SSID)) { + saved = true; + } + } + return saved; + } + + //断判某个wifi是否是连接成功的那个wifi + public boolean isConnectedWifi(Context context, String myssid) { + WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + if (isWifiConnect(context)) { + WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); + String ssid = wifiInfo.getSSID(); + return ssid != null && ssid.contains(myssid); + } else { + return false; + } + } + + //判断wifi是否连接 + public static boolean isWifiConnect(Context context) { + ConnectivityManager connManager = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + @SuppressLint("MissingPermission") + NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + return mWifi.getState() == NetworkInfo.State.CONNECTED; + } + + +} diff --git a/app/src/main/res/drawable-hdpi/alarm_add.png b/app/src/main/res/drawable-hdpi/alarm_add.png new file mode 100644 index 0000000000000000000000000000000000000000..4578a43952ef99fd9f680dcfde98b3391f1950b3 GIT binary patch literal 4594 zcmaJ_c|276`#+W}nPDt3wmL>gWtm|{b~A>Mr4Tb(7&Bv=7{*vr)L2GRgVGJzBGPaR z!&SP(U?>SSMO2onMGK;CMg7M8-tPDJ$M62m>zwmh&inm-p3n0N%r(5C)3E56okDUXp?9q5{RTSNnm2+k*HX!L|epPx>ln8`m_lG z{0qXQ*&_bq6v1OJ=tyT!LA0@%5!n=p1Th$6q&XUcLGA=mrbv{Dsp!NQAE6eQQ*2FDVQF|v_*(K{m&92qyLeOiv2rGqJWtslA=wJ#-{5_ z`U&*#`2V4ik^i7$ncmd@`ul$h$NDBkQ%$_7vGh0wS(LaC-E~vZR*noRiAiVp(&p>R&ScA+dSe{%73a$F=eiusdE`7am$uiW)gh>R9l##0&L z@l=X4gB}U~wPdUCfA+FUg(W|7cU@;}Z4RdK;}x=fz0)(SbdBn^dxEZ6vw% z<>gXF`55+-D=og&ewR;7>yAe_DdRO&eA2xGf)-9_G^g<*5}!1WDE4CAGSo@%!@6dU zkEa_9KOg?^tu%J%*~`_yr7YQlFG_gA)X&dCKQtxm>u2@JB;rE-y!I;yFLE1VA_lE8 z{c15fpp-+3ycr;~kW<_qTFhn?QGW z=sMR?B10mxzs6a3OR`i@hu4UX1Qzi^(|y$JIG>|-wQ{UK`7G}+&-H)-N6hI}aJ5qa zYae%*TM_g8J;wXjOyXd&#{q4CMR7;c;PX~!r=-pgt=@x;CA`8%=}KwX={)RGHMf{B zL#)X(mq&A}x&DOtWgRhyQZQxJG$YR1snq<0vOu|U16PfyCBaIsl|vVz_utyvvw(9e zYL@$CL!&;q8RW@+&$FdT(XM@J?d#Ga9;?{-_{rb{LKi4D#S|X#L(d!fnLJFnzdQo> zqq%!!Vc$CGFKiBt44v$IbMk9^uCd1GJB=A{IKN@Gzx63bILU3P4IK)*hAbou$xdI` z%YiWR_22vxKH>Vv3hEXJjG)cl)ce!Qh>mB4s!~lv4ODPKfHV z$#h+QP}1&M_$&VUBd{?nTHnc!d&a?5v3Nmr)snwt4Hv{ufEgK2UGxyw+z|D$j@y`3}aZL-N)A8|^4i z+`IHlY|+OZB+l}4{iRZ-VT3;OT*UjDF7SC38<8_vWq+#1cd8ms3pyi|gj7m2JE;)g zN&(?U?ZI6yCh07Js?{d0YppD-4_}}AiG*giTQ8{6c14J7#YW6P2j~~vc0j%B<~j?u zbL7W*mLiwJcj)&S#0sDa4)3v<0z_YeAgiW01H(2y-0RU}yg?yEt8 zVf4jfUJDl^Fc;bi^cL7hn|rzDf=%4#h^$U>=}17+060m^>90&UdxCc^tUj)_2W;$o zdp2EfzC7Bc-bhzL)gqb136Kpw=BC^t=V&lX4;f8Y2_N-ZbdlMYk^*Dt%Yre5T_-`W@m7R}w==VU3?F*Qy?M0^ z|KXS?b75QXjCdAtjc{HRt&+{@-L$1DXaZ2GzK1!p0bjq;w#QLJwu zfijbom+?0EkaX;<*N!vax9Gz>-lukHom{nPQ5bHIDJe(r`!_g;4XX0N#%F)X@@-Ok zFYPwh?=e)@P2PQ4{NR*p_;ooF=N925`0PupYtc&0Nb

cGI&;w!C;-H2cUWjNFa* zEW1OasdJE$)6@D*&6&1lf+0cQq4y`9^=ESC$n1ig5-$2}HrA6o=x};+=9fKXVnhW+ z&yQUoLx|Q$39^32D?EgDu@GvrjbvmJ!aQz;z`jT$$?_*pK3rn9LJ*U6)`~tb(<`AU zihvK=2gTuRu$`}}c$Y3f@K~ovP5aN9%5r8=+C3{JS}}W9SgXSVI>4Phm9 z**oNKg6WIP1*fvNN9o*b56xejKVib1a9h6I0efc`wi20Qc!(Q(;MZrQ-8R-|!r=Ev zS|dgF7*xJ)PPnerjd+6sWJ!8|VnGiyV2n&ZvOG9Ftr4^KXQbKq4F z4=bONi!i^`q8A_7@kr{+xBCt@hO*}K34~)`r1_xqk=tKCcYpy)3Mv&>cTV7&Bd$Ga zeXvz3ym95tXA9UM!Kt}rJ1P{o=fKdhyx7w9RrNc28TPrL=OcLZEG+kU|Fi5apQqK| z4-Qti>-#33Tb2e6f?6_J!+y2K6L@^;*cQ|3lYwcp(Bm9io z<^4<9jw3yFSgqBH{Wq-3#7g(=kQ!s{0yrGoV9u{FX+UXdlPJ+e#zN!uT)b6c`Rd36 zTdUk4joL8)*oJ*@65w=!M~QLl4FHmD@TrA6SC6*=*i*k51V9=$ECOJrktp}-8Wgi> zF$YL-CA3j?eR6PEDsMwhAgB*$y_8$Q-?M%_4^snzZv!lVQ-Kxg8Uy@fopDgJe_GoU zh|ZRHlR<~$<1L6ef2MJo3M=EkW9SL>tv#IC3y@^flBYsmPCq$!azlZGn6r+4~ zvafMqU*V4vTI#l%G4WYHLaxh=2?O~3P9Z*peWlixs|F*3bvW+F&_}}MvZPdL(Z0FA z4Wh_E3KWH2iXT>qU&12_1ZDMqs>Cp|%V_VCqhQ#>QK=Hhp|h6<@fJpU0nHa{k#8c? zyL0hFDGuf_uCrz!y~^*x+>%<3+va;oDg@6wa@{!i{mXDmde}q~e(gRO5fsZEQ+*vk zN_oF=Bx3op*5{*l`@k++ZlJDoXVClVopZJmZ-RN?*<%(6>CU~Fh}`@@sl4hgAHxWX zBLJkrmDV)u#gf^gIOm*}bWb?GwF8QQyYf zoVJ>$anp}>>SQo%3Pv-ZC(puX1$_aI8=jU88ZJPEH=J+SVH>c8DV01Qf5DH3i&M^2 z@6cT|WrloXm}LXFMZZkDEQ%1d?ADd9!YN$|*nvL2`trC$ zvff2YV8!ZH!07-WrhP!eQN3hJk;0N`>^!1G>eViBh`e6PzgleXD)d)d z+(|oc9s!-$lX*mL4z61MW&DpiY<>C}jls2)0^0TN^O|djOBU=IelIDKPwC_P$ z|M>Tc^v4O^o#KOWyll0XaIIbH<^8>ZtxEFmWD(!ctv(*`(@(=Vsd|{YPl2!UMHfa^3{w!9n5}I)0~DT8Rd8lhY@B zowKcmBX17RXnHiK86%$0p>jVG&HDS!m%T`Qn_AIEP)*llh@aDXJwKqcc$?>HpO$O{ zmo}ecME!9YtD$Kn<}UQN+V-|5SzID%sN-De0~5XMq{s(R4`id4X6t)y5no=PtBpxJ z8i3_cs7Ds{Vs>AO@iW{K$Rx*(HD)~75B*E7NAuQ!a5fy z%54yJ`jH(#zQKz)_4pwO7_n)A+tzs282o{vCP>HJC2mKfFuc_@zL~#6!qnx?HtLGc z%A>&QN0!x{kN4Ho-w6>G)&?f%I+?PwnIS7xg44$pwEs-V^`ZG0thKLBc%~L!S~wtI wHBn>#xYt$cVVMsls`3<1O(&u3hpZ_emR)zX>$T+Q`d=7VCr^9>F6iX{0GkcarvLx| literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/icon_add.png b/app/src/main/res/drawable-hdpi/icon_add.png new file mode 100644 index 0000000000000000000000000000000000000000..0ee142222c04040822c8a81d8b1b90542a9240b3 GIT binary patch literal 2455 zcma)8ZB!Fy7EbvtT?8u!RDzB{1YPnmL4paSAPGp&00xu~7bG7Oh>%Q@8B8RKVppwV zQK?!Af>qEKMNc)l)M6rg3J4`ai3=X^KolVqv0_DFQNf)ksHZM_cFxSa^WO8^=RWVf z&yU$38@<6tqW;wvHCY7s1e0FIQO z4)GwqXq%!53dZ5A36l6kG?BZGA%vwQz6C>4OXXNL4i_Avmh**~5DEyObcu{f7_PZN z03;$NAt8WE;mTQ1h9oja3B~0^#|v{Zg>(@i~cKJ~BfxyOyw7`KEJ4 zvuk0^noGvSkS&9KZ_qO#%srORx3J3<`t%l{`~z) zZ3V@FXGP|*eKx?LybQh?||gQ zxGsYh^eJYh6y5EkugSUJzb%tfl0z~*@N}NnXb*0xS|XLL)!*@PjbwO^9lu(>)R<~Y zc~)?GE!SwfXF&Tfd{3;~AfYh;OekUQ#(!$>eRS;QzFTuH(QaOsUGS~EGG0w{>`TdH zH+fdMN9Oz?`h4_MAFYpg@Z-K+SM%D4|7sBs_g{1KH+6+>^*LX5OSfKQ)9E$mM>w~q zZjx11+F=vXnG{qP<(@eT=~LVyqD*)7zRcZK?)C?d6epgvQd}juZYr@#5_*37>qFPZ zs3F{*jb}r1s;pg;k6S7FNv@h;+ujIcY?bC>z^>;uR#qS7?FtPA02dbr2OG=w{|UW8 zzL)q*mfkzVNvG3wjt@k9u0qpF(*`#ZVi=s8ib8*`1v@ zCbu>YbhWqlr`Bd0FpIuQ+S?Y<^Ve#>pK5Bf8_sW>=nbmd;yypvj{YDqb;YZ+88rGS;1( z>Q}%xVU|9LEX;N7TKD%vvWv%^C2rGQ!F|xuybnV*MyrM0^INzNY{E9`$dA=M4F+VW z&F!#EQM`!w{Q2{}JGrVP)pw&E_ss40Tt4~JP~L0R%;-J{y_@LUX2yzqZK-LPF+v^t z&Sviln_PZ474yebbl%@C&x!qw=h$~0i@NiG8%g%QD9QFIVo1sSsJvoX%h^!b8B?P3 zeD45-b}a0EdWUty0+}HC43Bez^xCaIVQv*C8NTfDYW%WjUWe`8(#Dec*~AV_hiybP zg?jilm|o@Nty%{2*8xqdhgeNI|ED2~{?b=d)OumA_p!05YA;i4P=0{%X;Fy4Etwp( zG^Jg?%)F(1&0)V+yLNQs7j}-P;YY1F1r7Lrh>zCY-`;v?J^ICl+ebFE+QXM~uUtYK z9<~>qI<2BTFMIaPzNhizq0pcxjb@E*Rk3a1v-+(3iSA_MUPV^(xO(h|yrqNQ;|YT3 z3lvB%`%NloFvJ;NoeAIHz#In*h{l0xz zUpm~MbCC-}k`XNvwq@|PO71@)nT5oZTK3)5bV}&{1 z(D3r(R(EiGJ6B!zxL*VQ-sIG|G=>zAbLt5{_}JosGe|SJ!7wr^u&eO!d$|w^KCdU_ zLg%J>E9ZzRY{4Nxhqyhzc4LEI%Q^SeTkC_(L%-O(EZH#ZRZ3d%(&v276N>J*f^@zo gjh`HipCs4f>XSW(6WXg%Ex$^f@M!kMu(aL(0i*oOBme*a literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/icon_back.png b/app/src/main/res/drawable-hdpi/icon_back.png new file mode 100644 index 0000000000000000000000000000000000000000..89a7ad54c2fcf9130b4c8364dfd583a811a09132 GIT binary patch literal 843 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/icon_missed.png b/app/src/main/res/drawable-hdpi/icon_missed.png new file mode 100644 index 0000000000000000000000000000000000000000..1016ce462e91bea02fd49f39f8335ed71b6dd0b3 GIT binary patch literal 1795 zcmV+e2mJVnP)Px*y-7qtRCr$PoPVekRTRh1ncXGHURnMlmALDhvzw_{qk_n&*L!nE-b2F_Lc*uG^>9wy*DNfr-JLsg z@10p6bN}6QzW1EZoI5l3$1FnLv1K+Ph^0p02M5en>>O$LT`|@c{tb z7Wy0_q6<{~69E)LtObB}SLnJdAPON~0)Pjbl2(Q|4jv%lo388LZ3SQiyhfi{L2Rxf z8A~L@@$gi9n!(1ZK+p3&M#Lp5R|WvO9-=Nh$w3*Q5aKlexK|P0m{|}6H`Hpiuj2Ta zuvG!0Vxtm^5$;!CcGPs}1jrOTr3w^6Tnqra0ANbeoPr=&QmfUr zCG}70*9ugq)p*(}-6uQsA6bFE?{8)1#YvNB^6Miad6Q4IwSd^%f8;|ZD%g$yg%D>0 zz##yb93`aq`<+DewxX>uvo;X5;YAK%A;dxe*kLS_|Adwi(H6s+9py3u=y~2#i1>ts zWS0}s%NBJ1Czkp$V}27F2~0KLWs|I*BRzYR?M7b;|p@YDwSoyw?#? zX=PRsR7*1=iky?{=-c#-x(7Z405)HCkM;EQoIh>av=cUyw5c5h(8gT2k^=BrHx76ie1)qPi! z{o2rq1So`94FDSrcb>_Hli?i3O=yR!3iPW z2Y^0}I*xO5Z*T7> zru4GXQ35D~^L>8}Ge2!G(CtKYi$T3iq?7^f-@pHyAPDvXz(uAaod{K^3^06{$a8lu zngR#_`%0zKqH?+Xhe6F$rD6dLA?^l%D-A}ui-@i=sF$i#Y=EBUEk(q4Oh$=_J6zXY zWKuINt=Is=D*O}xj3#`#PVW){92gi_P$(3>0Dv=1UTH+!?7Hr%B${$>0}-!a=5rBo z->FllHl}f)DG@+R50nPCcZp0Gas2Ah-!D%9kmEiEFmqahz9Mf%H7@5=7h% z02fAy+JvYDPzF9YIC#C|I1-{0l}OUxnfXgZ6o@#$%s&Ibwanayh_h5RZ9&uqC=>8~ z{}E<>PBodV>})_Z0#E|+JZ}>suFMLKYQLr-8Uq+URK|a&p_*5!b|xVj1sD!z<9jHU z=o&d%XB=Qyi2?vzONkqkMZ{IE>u%N&v;r`MI067?=>(UOuhyAuYXC!te*(bNlt3iz z#&Mjby}iBfB@wU+Fod`V0OltNE=`}LhdiwV3?aS+0C%JbBw=3*iAYWglv^qQLx^&7 zUT)HNdz(!}asy4Nr3Ns3#o55jk1Iu%ozbtwV)61yrBYW3Ayt4OL^k0Ls9^r7&5Eu|DEfNlMpd z(xgdKr%#`LR7EE*M%! z1;9qY;g;zN!~4#vJYvI>!d(S$+_07)jU6NDM3I@dR;$%pRY^D7btOO)HxzPDUQBL&U|*EdQ@Y{&$0^ld^K#^ikcf=exE7TUA7O+<0*a zH0i-8gZ=FIuW6tD>o&=#l(H-ys$l>@Xye8SxW lEpciqn*-D&o&(eb_%C2Kw{Pw^XH5VA002ovPDHLkV1la~Gz|a% literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/icon_nodata.png b/app/src/main/res/drawable-hdpi/icon_nodata.png new file mode 100644 index 0000000000000000000000000000000000000000..e1eb6e3bf9a7c9d424a02ea9bd73343aa6d7afd9 GIT binary patch literal 13433 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/icon_wifi_available.png b/app/src/main/res/drawable-hdpi/icon_wifi_available.png new file mode 100644 index 0000000000000000000000000000000000000000..fbb1df8026f0ab70228e80239ed40601ab30992e GIT binary patch literal 4421 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 b!Zmq1Uwf-s79#5AF9JYl8^h~0o#Xxo@Z4R$ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/icon_wifi_saved.png b/app/src/main/res/drawable-hdpi/icon_wifi_saved.png new file mode 100644 index 0000000000000000000000000000000000000000..c36325680ff7e1a772f65dc4c9ec848694bf0060 GIT binary patch literal 5649 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/settings1.png b/app/src/main/res/drawable-hdpi/settings1.png new file mode 100644 index 0000000000000000000000000000000000000000..1e9fdfe851a571c6b5ec4b3ea300b32523b31901 GIT binary patch literal 4205 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/add_alarm_background.xml b/app/src/main/res/drawable/add_alarm_background.xml new file mode 100644 index 0000000..c42196d --- /dev/null +++ b/app/src/main/res/drawable/add_alarm_background.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/add_alarm_cancel_background.xml b/app/src/main/res/drawable/add_alarm_cancel_background.xml new file mode 100644 index 0000000..493b32f --- /dev/null +++ b/app/src/main/res/drawable/add_alarm_cancel_background.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_wifi.xml b/app/src/main/res/drawable/background_wifi.xml new file mode 100644 index 0000000..0e6b016 --- /dev/null +++ b/app/src/main/res/drawable/background_wifi.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_wifi_white.xml b/app/src/main/res/drawable/background_wifi_white.xml new file mode 100644 index 0000000..81fbe5c --- /dev/null +++ b/app/src/main/res/drawable/background_wifi_white.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bt_activation_normnl.xml b/app/src/main/res/drawable/bt_activation_normnl.xml new file mode 100644 index 0000000..9cfee8e --- /dev/null +++ b/app/src/main/res/drawable/bt_activation_normnl.xml @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bt_activation_pressed.xml b/app/src/main/res/drawable/bt_activation_pressed.xml new file mode 100644 index 0000000..8551266 --- /dev/null +++ b/app/src/main/res/drawable/bt_activation_pressed.xml @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bt_activation_selector.xml b/app/src/main/res/drawable/bt_activation_selector.xml new file mode 100644 index 0000000..3b50ee2 --- /dev/null +++ b/app/src/main/res/drawable/bt_activation_selector.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/default_button_bg.xml b/app/src/main/res/drawable/default_button_bg.xml new file mode 100644 index 0000000..45b8ea0 --- /dev/null +++ b/app/src/main/res/drawable/default_button_bg.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/default_button_cancel_bg.xml b/app/src/main/res/drawable/default_button_cancel_bg.xml new file mode 100644 index 0000000..c9d6327 --- /dev/null +++ b/app/src/main/res/drawable/default_button_cancel_bg.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/delete_wifi_cancel_background.xml b/app/src/main/res/drawable/delete_wifi_cancel_background.xml new file mode 100644 index 0000000..3db6e4d --- /dev/null +++ b/app/src/main/res/drawable/delete_wifi_cancel_background.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/edit_background.xml b/app/src/main/res/drawable/edit_background.xml new file mode 100644 index 0000000..8014d90 --- /dev/null +++ b/app/src/main/res/drawable/edit_background.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tv_times_bg.xml b/app/src/main/res/drawable/tv_times_bg.xml new file mode 100644 index 0000000..e99e5ff --- /dev/null +++ b/app/src/main/res/drawable/tv_times_bg.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tv_times_bg_loop.xml b/app/src/main/res/drawable/tv_times_bg_loop.xml new file mode 100644 index 0000000..01b3f5b --- /dev/null +++ b/app/src/main/res/drawable/tv_times_bg_loop.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tv_times_bg_loop_selector.xml b/app/src/main/res/drawable/tv_times_bg_loop_selector.xml new file mode 100644 index 0000000..95d6366 --- /dev/null +++ b/app/src/main/res/drawable/tv_times_bg_loop_selector.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tv_times_bg_offday.xml b/app/src/main/res/drawable/tv_times_bg_offday.xml new file mode 100644 index 0000000..8aad1c6 --- /dev/null +++ b/app/src/main/res/drawable/tv_times_bg_offday.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tv_times_bg_offday_selector.xml b/app/src/main/res/drawable/tv_times_bg_offday_selector.xml new file mode 100644 index 0000000..3ba3a12 --- /dev/null +++ b/app/src/main/res/drawable/tv_times_bg_offday_selector.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tv_times_bg_once.xml b/app/src/main/res/drawable/tv_times_bg_once.xml new file mode 100644 index 0000000..2469bdb --- /dev/null +++ b/app/src/main/res/drawable/tv_times_bg_once.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tv_times_bg_once_selector.xml b/app/src/main/res/drawable/tv_times_bg_once_selector.xml new file mode 100644 index 0000000..a22ac74 --- /dev/null +++ b/app/src/main/res/drawable/tv_times_bg_once_selector.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tv_times_bg_work.xml b/app/src/main/res/drawable/tv_times_bg_work.xml new file mode 100644 index 0000000..5cbb751 --- /dev/null +++ b/app/src/main/res/drawable/tv_times_bg_work.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tv_times_bg_work_selector.xml b/app/src/main/res/drawable/tv_times_bg_work_selector.xml new file mode 100644 index 0000000..686b6dd --- /dev/null +++ b/app/src/main/res/drawable/tv_times_bg_work_selector.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/wifi_passwd_background.xml b/app/src/main/res/drawable/wifi_passwd_background.xml new file mode 100644 index 0000000..8e46c4d --- /dev/null +++ b/app/src/main/res/drawable/wifi_passwd_background.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_control.xml b/app/src/main/res/layout-land/activity_control.xml index 3aeebc8..80e4a0d 100644 --- a/app/src/main/res/layout-land/activity_control.xml +++ b/app/src/main/res/layout-land/activity_control.xml @@ -89,7 +89,7 @@ android:layout_marginStart="@dimen/dp_8" android:adjustViewBounds="true" android:scaleType="centerCrop" - android:src="@drawable/time1" + android:src="@drawable/settings1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -98,7 +98,7 @@ android:id="@+id/tv_flashlight" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="00:00" + android:text="系统设置" android:textColor="@color/white" android:textSize="@dimen/sp_15" app:layout_constraintBottom_toBottomOf="parent" @@ -112,7 +112,7 @@ android:id="@+id/tv_flashlight_switch" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="11月15日" + android:text="其他设置" android:textColor="@color/white" android:textSize="@dimen/sp_12" app:layout_constraintBottom_toBottomOf="parent" @@ -121,6 +121,53 @@ app:layout_constraintVertical_bias="0.2" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -275,11 +275,11 @@ android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/dp_8" - android:layout_marginTop="@dimen/dp_8" + android:layout_marginStart="@dimen/dp_4" + android:layout_marginTop="@dimen/dp_4" android:text="爱心闹钟" android:textColor="@color/default_text_color" - android:textSize="@dimen/sp_15" + android:textSize="@dimen/sp_13" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -333,11 +333,11 @@ android:id="@+id/textView7" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/dp_8" - android:layout_marginTop="@dimen/dp_8" + android:layout_marginStart="@dimen/dp_4" + android:layout_marginTop="@dimen/dp_4" android:text="紧急呼叫" android:textColor="@color/default_text_color" - android:textSize="@dimen/sp_15" + android:textSize="@dimen/sp_13" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -439,7 +439,7 @@ android:layout_marginTop="@dimen/dp_4" android:text="一键加速" android:textColor="@color/title_gray" - android:textSize="@dimen/sp_15" + android:textSize="@dimen/sp_13" android:textStyle="bold" android:visibility="gone" app:layout_constraintStart_toStartOf="parent" @@ -500,11 +500,11 @@ android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/dp_8" - android:layout_marginTop="@dimen/dp_8" + android:layout_marginStart="@dimen/dp_4" + android:layout_marginTop="@dimen/dp_4" android:text="健康码" android:textColor="@color/title_gray" - android:textSize="@dimen/sp_15" + android:textSize="@dimen/sp_13" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -538,11 +538,11 @@ android:id="@+id/tv_app" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/dp_8" - android:layout_marginTop="@dimen/dp_8" + android:layout_marginStart="@dimen/dp_4" + android:layout_marginTop="@dimen/dp_4" android:text="快捷应用" android:textColor="@color/default_text_color" - android:textSize="@dimen/sp_15" + android:textSize="@dimen/sp_13" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -576,11 +576,11 @@ @@ -611,11 +611,11 @@ @@ -647,11 +647,11 @@ android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/dp_8" - android:layout_marginTop="@dimen/dp_8" + android:layout_marginStart="@dimen/dp_4" + android:layout_marginTop="@dimen/dp_4" android:text="通讯录" android:textColor="@color/default_text_color" - android:textSize="@dimen/sp_15" + android:textSize="@dimen/sp_13" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout-land/fragment_custom_back.xml b/app/src/main/res/layout-land/fragment_custom_back.xml deleted file mode 100644 index 68063cd..0000000 --- a/app/src/main/res/layout-land/fragment_custom_back.xml +++ /dev/null @@ -1,421 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout-land/item_goods_list.xml b/app/src/main/res/layout-land/item_goods_list.xml index 24cc978..ae794be 100644 --- a/app/src/main/res/layout-land/item_goods_list.xml +++ b/app/src/main/res/layout-land/item_goods_list.xml @@ -110,7 +110,7 @@ android:layout_height="wrap_content" android:layout_marginStart="@dimen/dp_4" android:maxLines="1" - android:text="秒杀价格" + android:text="秒杀" android:textColor="@color/red" android:textSize="@dimen/sp_14" app:layout_constraintBottom_toBottomOf="@+id/tv_buying_price" diff --git a/app/src/main/res/layout-port/activity_control.xml b/app/src/main/res/layout-port/activity_control.xml index 664ec9d..dbf13cb 100644 --- a/app/src/main/res/layout-port/activity_control.xml +++ b/app/src/main/res/layout-port/activity_control.xml @@ -76,12 +76,12 @@ @@ -90,28 +90,75 @@ android:id="@+id/tv_flashlight" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="00:00" + android:text="系统设置" android:textColor="@color/white" - android:textSize="@dimen/sp_17" + android:textSize="@dimen/sp_15" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintHorizontal_bias="0.2" + app:layout_constraintHorizontal_bias="0.234" app:layout_constraintStart_toEndOf="@+id/iv_flashlight" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintVertical_bias="0.3" /> + app:layout_constraintVertical_bias="0.32" /> + app:layout_constraintTop_toBottomOf="@+id/tv_flashlight" + app:layout_constraintVertical_bias="0.2" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -293,7 +293,7 @@ android:layout_marginTop="@dimen/dp_16" android:text="爱心闹钟" android:textColor="@color/title_gray" - android:textSize="@dimen/sp_17" + android:textSize="@dimen/sp_14" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -358,7 +358,7 @@ android:layout_marginStart="@dimen/dp_8" android:text="紧急呼叫" android:textColor="@color/title_gray" - android:textSize="@dimen/sp_17" + android:textSize="@dimen/sp_14" android:textStyle="bold" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -429,7 +429,7 @@ android:layout_marginStart="@dimen/dp_8" android:text="一键加速" android:textColor="@color/title_gray" - android:textSize="@dimen/sp_17" + android:textSize="@dimen/sp_14" android:textStyle="bold" android:visibility="visible" app:layout_constraintBottom_toBottomOf="parent" @@ -615,7 +615,7 @@ android:layout_marginTop="@dimen/dp_16" android:text="快捷应用" android:textColor="@color/title_gray" - android:textSize="@dimen/sp_17" + android:textSize="@dimen/sp_14" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -674,7 +674,7 @@ android:layout_marginTop="@dimen/dp_16" android:text="家庭空间" android:textColor="@color/white" - android:textSize="@dimen/sp_17" + android:textSize="@dimen/sp_14" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -711,7 +711,7 @@ android:layout_marginTop="@dimen/dp_16" android:text="AI问诊" android:textColor="@color/title_gray" - android:textSize="@dimen/sp_17" + android:textSize="@dimen/sp_14" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -747,7 +747,7 @@ android:layout_marginTop="@dimen/dp_16" android:text="通讯录" android:textColor="@color/title_gray" - android:textSize="@dimen/sp_17" + android:textSize="@dimen/sp_14" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout-port/item_goods_list.xml b/app/src/main/res/layout-port/item_goods_list.xml index 78ff5ca..69ca466 100644 --- a/app/src/main/res/layout-port/item_goods_list.xml +++ b/app/src/main/res/layout-port/item_goods_list.xml @@ -81,7 +81,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/dp_4" - android:text="秒杀价格" + android:text="秒杀" android:textColor="@color/red" android:textSize="@dimen/sp_8" app:layout_constraintBottom_toTopOf="@+id/progressBar" diff --git a/app/src/main/res/layout/activity_add_alarm_clock.xml b/app/src/main/res/layout/activity_add_alarm_clock.xml new file mode 100644 index 0000000..22481ae --- /dev/null +++ b/app/src/main/res/layout/activity_add_alarm_clock.xml @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +