From fc767791f329cfda5494811cf46932199a800300 Mon Sep 17 00:00:00 2001 From: kangshulong Date: Thu, 6 Nov 2025 10:55:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A8=E5=BF=97=E4=BB=A3=E7=A0=81=E9=A6=96?= =?UTF-8?q?=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 + README.md | 1 + app/.gitignore | 5 + app/build.gradle | 108 ++ app/libs/SAD-release-1.0.9.aar | Bin 0 -> 63812 bytes app/platform_rk.keystore | Bin 0 -> 2376 bytes app/proguard-rules.pro | 74 ++ app/src/main/AndroidManifest.xml | 127 ++ .../com/ik/download/DownLoadAppListener.java | 5 + .../java/com/ik/download/DownloadAppTask.java | 127 ++ .../java/com/ik/download/DownloadImgTask.java | 101 ++ .../com/ik/mboxlauncher/SystemService.java | 372 ++++++ .../java/com/ik/mboxlauncher/VersionBean.java | 25 + .../receiver/LauncherReceiverFromOther.java | 30 + .../ik/mboxlauncher/ui/ADSWindowManager.java | 200 ++++ .../ik/mboxlauncher/ui/CategoryActivity.java | 165 +++ .../ik/mboxlauncher/ui/FragmentManager.java | 87 ++ .../java/com/ik/mboxlauncher/ui/Launcher.java | 978 ++++++++++++++++ .../com/ik/mboxlauncher/ui/MyActivity.java | 64 + .../com/ik/mboxlauncher/ui/MyApplication.java | 107 ++ .../ui/OnRefresnLauncherListener.java | 6 + .../mboxlauncher/ui/SplashscreenActivity.java | 234 ++++ .../ik/mboxlauncher/ui/StartupBroadcast.java | 136 +++ .../ui/adapter/CustomAppAdapter.java | 240 ++++ .../ui/adapter/LocalAppAdapter.java | 226 ++++ .../ui/adapter/MusicAppAdapter.java | 228 ++++ .../ui/adapter/MyAppInfoAdapter.java | 238 ++++ .../ui/adapter/RecommendAppAdapter.java | 224 ++++ .../ui/adapter/ShortAppInfoAdapter.java | 198 ++++ .../ui/adapter/StatusAdapter.java | 415 +++++++ .../ui/adapter/VideoAppAdapter.java | 224 ++++ .../ik/mboxlauncher/ui/base/BaseActivity.java | 307 +++++ .../ik/mboxlauncher/ui/base/BaseFragment.java | 179 +++ .../mboxlauncher/ui/base/BaseUICallback.java | 17 + .../mboxlauncher/ui/base/BaseUIPresenter.java | 28 + .../ui/base/FragmentActivity.java | 206 ++++ .../mboxlauncher/ui/base/NotifyInterface.java | 16 + .../ik/mboxlauncher/ui/base/StatusLoader.java | 183 +++ .../ui/fragment/AppsFragment.java | 135 +++ .../ui/fragment/CategoryFragment.java | 334 ++++++ .../ui/fragment/LocalFragment.java | 122 ++ .../ui/fragment/MainFragment.java | 441 +++++++ .../ui/fragment/MusicFragment.java | 126 ++ .../ui/fragment/RecommendFragment.java | 121 ++ .../ui/fragment/VideoFragment.java | 124 ++ .../com/ik/mboxlauncher/view/AdMultiView.java | 484 ++++++++ .../view/CountdownTimeTextView.java | 138 +++ .../mboxlauncher/view/CustomRecyclerView.java | 270 +++++ .../view/CustomRecyclerViewer.java | 290 +++++ .../ik/mboxlauncher/view/HomeMultiView.java | 404 +++++++ .../com/ik/mboxlauncher/view/LoadingView.java | 272 +++++ .../com/ik/mboxlauncher/view/MultiView.java | 81 ++ .../ik/mboxlauncher/view/MyLinearLayout.java | 56 + .../mboxlauncher/view/MyRelativeLayout.java | 450 +++++++ .../ik/mboxlauncher/view/MyScrollView.java | 37 + .../com/ik/mboxlauncher/view/MyTextView.java | 25 + .../com/ik/mboxlauncher/view/SplashView.java | 275 +++++ .../ik/mboxlauncher/view/TimeTextView.java | 99 ++ app/src/main/res/anim/anim_alpha_show.xml | 5 + .../main/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 2574 bytes .../main/res/drawable-ldpi/ic_launcher.png | Bin 0 -> 1723 bytes app/src/main/res/drawable/app.png | Bin 0 -> 1899 bytes app/src/main/res/drawable/app_border.xml | 6 + app/src/main/res/drawable/app_info_bg.xml | 5 + app/src/main/res/drawable/app_info_border.xml | 6 + app/src/main/res/drawable/app_item_bg.xml | 5 + app/src/main/res/drawable/app_item_border.xml | 6 + app/src/main/res/drawable/app_item_select.xml | 5 + app/src/main/res/drawable/bg.webp | Bin 0 -> 3780 bytes app/src/main/res/drawable/frag_bg.webp | Bin 0 -> 10060 bytes app/src/main/res/drawable/frame.9.png | Bin 0 -> 93 bytes app/src/main/res/drawable/img_chrome.webp | Bin 0 -> 1604 bytes .../main/res/drawable/img_filemanager.webp | Bin 0 -> 3278 bytes app/src/main/res/drawable/img_hbomax.webp | Bin 0 -> 1828 bytes .../res/drawable/img_miracastreceive.webp | Bin 0 -> 5084 bytes app/src/main/res/drawable/img_music.webp | Bin 0 -> 4606 bytes app/src/main/res/drawable/img_netflix.webp | Bin 0 -> 2168 bytes app/src/main/res/drawable/img_primevideo.webp | Bin 0 -> 2720 bytes app/src/main/res/drawable/img_recommend.webp | Bin 0 -> 7940 bytes app/src/main/res/drawable/img_setting.webp | Bin 0 -> 2630 bytes .../main/res/drawable/img_status_ethernet.png | Bin 0 -> 924 bytes .../main/res/drawable/img_status_sdcard.png | Bin 0 -> 840 bytes app/src/main/res/drawable/img_status_usb.png | Bin 0 -> 1044 bytes app/src/main/res/drawable/img_video.webp | Bin 0 -> 12912 bytes app/src/main/res/drawable/img_youtube.webp | Bin 0 -> 1876 bytes app/src/main/res/drawable/item_add_img.png | Bin 0 -> 498 bytes app/src/main/res/drawable/item_child_1.png | Bin 0 -> 3151 bytes app/src/main/res/drawable/item_child_2.png | Bin 0 -> 3148 bytes app/src/main/res/drawable/item_child_3.png | Bin 0 -> 3145 bytes app/src/main/res/drawable/item_child_4.png | Bin 0 -> 3148 bytes app/src/main/res/drawable/item_child_5.png | Bin 0 -> 3144 bytes app/src/main/res/drawable/item_child_6.png | Bin 0 -> 3152 bytes app/src/main/res/drawable/item_img_add.png | Bin 0 -> 1118 bytes app/src/main/res/drawable/item_img_apps.png | Bin 0 -> 1418 bytes app/src/main/res/drawable/item_img_sel.png | Bin 0 -> 1707 bytes app/src/main/res/drawable/item_text_bg.xml | 9 + app/src/main/res/drawable/line.png | Bin 0 -> 2844 bytes app/src/main/res/drawable/local.png | Bin 0 -> 1079 bytes app/src/main/res/drawable/music.png | Bin 0 -> 2041 bytes app/src/main/res/drawable/recommend.png | Bin 0 -> 2121 bytes app/src/main/res/drawable/tab_apps_normal.png | Bin 0 -> 1686 bytes app/src/main/res/drawable/tab_apps_select.png | Bin 0 -> 1597 bytes .../main/res/drawable/tab_apps_selector.xml | 4 + app/src/main/res/drawable/tab_bg_selector.xml | 14 + .../main/res/drawable/tab_local_normal.png | Bin 0 -> 977 bytes .../main/res/drawable/tab_local_select.png | Bin 0 -> 911 bytes .../main/res/drawable/tab_local_selector.xml | 4 + .../main/res/drawable/tab_music_normal.png | Bin 0 -> 1749 bytes .../main/res/drawable/tab_music_select.png | Bin 0 -> 1637 bytes .../main/res/drawable/tab_music_selector.xml | 4 + .../res/drawable/tab_recommend_normal.png | Bin 0 -> 1752 bytes .../res/drawable/tab_recommend_select.png | Bin 0 -> 1628 bytes .../res/drawable/tab_recommend_selector.xml | 4 + .../main/res/drawable/tab_video_normal.png | Bin 0 -> 674 bytes .../main/res/drawable/tab_video_select.png | Bin 0 -> 689 bytes .../main/res/drawable/tab_video_selector.xml | 4 + app/src/main/res/drawable/video.png | Bin 0 -> 965 bytes app/src/main/res/drawable/wifi1.png | Bin 0 -> 1689 bytes app/src/main/res/drawable/wifi2.png | Bin 0 -> 1677 bytes app/src/main/res/drawable/wifi3.png | Bin 0 -> 1659 bytes app/src/main/res/drawable/wifi4.png | Bin 0 -> 1588 bytes app/src/main/res/drawable/wifi5.png | Bin 0 -> 1382 bytes .../res/layout-sw480dp/ad_multi_layout.xml | 35 + .../res/layout-sw480dp/add_apps_grid_item.xml | 42 + .../res/layout-sw480dp/apps_grid_item.xml | 58 + .../res/layout-sw480dp/childgrid_item.xml | 33 + .../main/res/layout-sw480dp/homegrid_item.xml | 20 + .../main/res/layout-sw480dp/homelist_item.xml | 12 + .../layout-sw480dp/layout_category_app.xml | 146 +++ .../layout-sw480dp/layout_custom_apps1.xml | 22 + .../res/layout-sw480dp/layout_rect_group1.xml | 145 +++ .../res/layout-sw480dp/layout_shortcut.xml | 21 + .../res/layout-sw480dp/layout_statusbar.xml | 39 + app/src/main/res/layout-sw480dp/main.xml | 49 + .../main/res/layout-sw480dp/multi_layout.xml | 37 + .../res/layout-sw540dp/ad_multi_layout.xml | 35 + .../res/layout-sw540dp/add_apps_grid_item.xml | 44 + .../res/layout-sw540dp/apps_grid_item.xml | 57 + .../res/layout-sw540dp/childgrid_item.xml | 34 + .../main/res/layout-sw540dp/homegrid_item.xml | 20 + .../main/res/layout-sw540dp/homelist_item.xml | 12 + .../layout-sw540dp/layout_category_app.xml | 147 +++ .../layout-sw540dp/layout_custom_apps1.xml | 19 + .../res/layout-sw540dp/layout_rect_group1.xml | 145 +++ .../res/layout-sw540dp/layout_shortcut.xml | 20 + .../res/layout-sw540dp/layout_statusbar.xml | 33 + app/src/main/res/layout-sw540dp/main.xml | 51 + .../main/res/layout-sw540dp/multi_layout.xml | 36 + .../res/layout-sw720dp/ad_multi_layout.xml | 35 + .../res/layout-sw720dp/add_apps_grid_item.xml | 44 + .../res/layout-sw720dp/apps_grid_item.xml | 58 + .../res/layout-sw720dp/childgrid_item.xml | 33 + .../main/res/layout-sw720dp/homegrid_item.xml | 20 + .../main/res/layout-sw720dp/homelist_item.xml | 11 + .../layout-sw720dp/layout_category_app.xml | 147 +++ .../layout-sw720dp/layout_custom_apps1.xml | 20 + .../res/layout-sw720dp/layout_rect_group1.xml | 145 +++ .../res/layout-sw720dp/layout_shortcut.xml | 20 + .../res/layout-sw720dp/layout_statusbar.xml | 33 + app/src/main/res/layout-sw720dp/main.xml | 50 + .../main/res/layout-sw720dp/multi_layout.xml | 37 + app/src/main/res/layout/activity_my.xml | 29 + .../res/layout/activity_splash_screen.xml | 36 + .../main/res/layout/add_apps_grid_item.xml | 42 + app/src/main/res/layout/childgrid_item.xml | 29 + app/src/main/res/layout/homegrid_item.xml | 15 + app/src/main/res/layout/homelist_item.xml | 12 + app/src/main/res/layout/launcher_layout.xml | 10 + .../main/res/layout/layout_category_app.xml | 89 ++ .../main/res/layout/layout_custom_apps1.xml | 22 + .../main/res/layout/layout_rect_group1.xml | 144 +++ app/src/main/res/layout/layout_shortcut.xml | 21 + app/src/main/res/layout/layout_statusbar.xml | 39 + app/src/main/res/layout/main.xml | 45 + app/src/main/res/layout/multi_layout.xml | 27 + .../main/res/raw/default_shortcut.shortcut | 6 + app/src/main/res/values-ar/arrays.xml | 27 + app/src/main/res/values-ar/strings.xml | 14 + app/src/main/res/values-es/arrays.xml | 27 + app/src/main/res/values-es/strings.xml | 17 + app/src/main/res/values-pt/arrays.xml | 27 + app/src/main/res/values-pt/strings.xml | 15 + app/src/main/res/values-zh-rCN/arrays.xml | 27 + app/src/main/res/values-zh-rCN/strings.xml | 17 + app/src/main/res/values-zh-rTW/arrays.xml | 27 + app/src/main/res/values-zh-rTW/strings.xml | 16 + app/src/main/res/values/arrays.xml | 27 + app/src/main/res/values/attrs.xml | 15 + app/src/main/res/values/colors.xml | 12 + app/src/main/res/values/strings.xml | 15 + app/src/main/res/values/styles.xml | 4 + app/src/main/res/xml/sharefile.xml | 6 + .../com/ik/mboxlauncher/ExampleUnitTest.java | 17 + build.gradle | 29 + gradle.properties | 21 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 +++ gradlew.bat | 84 ++ mylibrary/.gitignore | 1 + mylibrary/build.gradle | 61 + mylibrary/consumer-rules.pro | 0 mylibrary/proguard-rules.pro | 21 + .../com/android/ExampleInstrumentedTest.java | 26 + mylibrary/src/main/AndroidManifest.xml | 6 + .../src/main/java/com/android/MXQConfig.java | 25 + .../main/java/com/android/api/ServerApi.java | 30 + .../java/com/android/api/ServerInterface.java | 39 + .../java/com/android/api/biz/BaseBiz.java | 87 ++ .../main/java/com/android/api/biz/Biz.java | 27 + .../java/com/android/api/biz/CoreKeys.java | 17 + .../com/android/api/biz/OnBaseListener.java | 15 + .../com/android/api/biz/bizimpl/BizImpl.java | 114 ++ .../com/android/api/encrytion/AESUtil.java | 59 + .../com/android/api/encrytion/MD5Utils.java | 31 + .../com/android/api/encrytion/TimeUtil.java | 527 +++++++++ .../android/api/encrytion/UtilEncrypt.java | 103 ++ .../com/android/api/encrytion/UtilHex.java | 47 + .../android/api/response/BaseResponse.java | 31 + .../android/api/response/EventResponse.java | 14 + .../android/database/AbstractDaoMannager.java | 46 + .../java/com/android/database/DaoManager.java | 299 +++++ .../com/android/database/lib/AdsInfoBean.java | 177 +++ .../com/android/database/lib/AppBean.java | 105 ++ .../android/database/lib/AppConfigBean.java | 136 +++ .../android/database/lib/AppMonitorBean.java | 78 ++ .../database/lib/DownLoadTaskBean.java | 261 +++++ .../com/android/database/lib/EventBean.java | 79 ++ .../android/database/lib/GoogleADEvent.java | 107 ++ .../android/database/lib/LocalAppBean.java | 96 ++ .../android/database/lib/MusicAppBean.java | 94 ++ .../android/database/lib/NetShortAppBean.java | 100 ++ .../database/lib/RecommendAppBean.java | 94 ++ .../android/database/lib/RecordEventBean.java | 79 ++ .../android/database/lib/ShortAppBean.java | 96 ++ .../android/database/lib/TaskInfoBean.java | 122 ++ .../android/database/lib/VideoAppBean.java | 95 ++ .../device/MediaStateChangeObserver.java | 8 + .../device/MediaStateChangeReceiver.java | 76 ++ .../device/NetStateChangeObserver.java | 9 + .../device/NetStateChangeReceiver.java | 98 ++ .../com/android/download/AppExecutors.java | 77 ++ .../com/android/download/DownLoadManeger.java | 277 +++++ .../android/download/DownLoadTaskThread.java | 187 +++ .../com/android/download/DownloadAppTask.java | 160 +++ .../com/android/download/DownloadService.java | 192 +++ .../java/com/android/download/TaskQueue.java | 88 ++ .../com/android/eventbaus/EventBusUtils.java | 33 + .../com/android/eventbaus/MessageEvent.java | 33 + .../com/android/monitor/DataBeeObserver.java | 71 ++ .../com/android/monitor/MonitorManager.java | 115 ++ .../com/android/monitor/MonitorThread.java | 68 ++ .../android/monitor/impl/EventFactory.java | 100 ++ .../android/monitor/impl/EventInterface.java | 18 + .../android/monitor/impl/GoogleEventImpl.java | 84 ++ .../java/com/android/nebulasdk/ADManager.java | 460 ++++++++ .../com/android/nebulasdk/AppManager.java | 637 ++++++++++ .../com/android/nebulasdk/TaskManager.java | 489 ++++++++ .../com/android/nebulasdk/bean/ADInfo.java | 126 ++ .../nebulasdk/bean/ADInfoResponse.java | 18 + .../com/android/nebulasdk/bean/BaseBean.java | 27 + .../com/android/nebulasdk/bean/BaseEvent.java | 5 + .../com/android/nebulasdk/bean/BaseValue.java | 9 + .../android/nebulasdk/bean/EventDataInfo.java | 62 + .../android/nebulasdk/bean/EventResponse.java | 14 + .../android/nebulasdk/bean/FavNaviBean.java | 54 + .../nebulasdk/presenter/AppnetPresenter.java | 126 ++ .../presenter/CategoryAppPresenter.java | 93 ++ .../nebulasdk/presenter/DataBeePresenter.java | 77 ++ .../presenter/callback/AppnetCallback.java | 24 + .../presenter/callback/BaseCallback.java | 11 + .../presenter/callback/BlackListCallback.java | 13 + .../callback/CategoryAppCallback.java | 18 + .../presenter/callback/NetCallback.java | 14 + .../callback/StatisticsCallback.java | 17 + .../java/com/android/util/AppInstallUtil.java | 552 +++++++++ .../java/com/android/util/BitmapUtils.java | 138 +++ .../main/java/com/android/util/DateUtil.java | 418 +++++++ .../java/com/android/util/DeviceUtil.java | 502 ++++++++ .../java/com/android/util/EventBusType.java | 39 + .../java/com/android/util/FileSystem.java | 354 ++++++ .../main/java/com/android/util/FileUtil.java | 139 +++ .../java/com/android/util/GetEditionCode.java | 30 + .../main/java/com/android/util/GsonUtil.java | 130 +++ .../java/com/android/util/IntentUtil.java | 28 + .../java/com/android/util/LogManager.java | 236 ++++ .../main/java/com/android/util/LogUtils.java | 45 + .../com/android/util/MaxLengthWatcher.java | 64 + .../main/java/com/android/util/MimeType.java | 113 ++ .../main/java/com/android/util/NetUtil.java | 73 ++ .../java/com/android/util/NetworkType.java | 22 + .../java/com/android/util/NetworkUtil.java | 100 ++ .../com/android/util/PakageInstallUtil.java | 499 ++++++++ .../java/com/android/util/RKDeviceUtil.java | 425 +++++++ .../android/util/SharedPreferencesUtil.java | 91 ++ .../java/com/android/util/StringUtil.java | 1034 +++++++++++++++++ .../android/util/SystemBarTintManager.java | 549 +++++++++ .../java/com/android/ExampleUnitTest.java | 17 + settings.gradle | 3 + 299 files changed, 26337 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/libs/SAD-release-1.0.9.aar create mode 100644 app/platform_rk.keystore create mode 100644 app/proguard-rules.pro create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/ik/download/DownLoadAppListener.java create mode 100644 app/src/main/java/com/ik/download/DownloadAppTask.java create mode 100644 app/src/main/java/com/ik/download/DownloadImgTask.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/SystemService.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/VersionBean.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/receiver/LauncherReceiverFromOther.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/ADSWindowManager.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/CategoryActivity.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/FragmentManager.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/Launcher.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/MyActivity.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/MyApplication.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/OnRefresnLauncherListener.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/SplashscreenActivity.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/StartupBroadcast.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/adapter/CustomAppAdapter.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/adapter/LocalAppAdapter.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/adapter/MusicAppAdapter.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/adapter/MyAppInfoAdapter.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/adapter/RecommendAppAdapter.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/adapter/ShortAppInfoAdapter.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/adapter/StatusAdapter.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/adapter/VideoAppAdapter.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/base/BaseActivity.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/base/BaseFragment.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/base/BaseUICallback.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/base/BaseUIPresenter.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/base/FragmentActivity.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/base/NotifyInterface.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/base/StatusLoader.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/fragment/AppsFragment.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/fragment/CategoryFragment.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/fragment/LocalFragment.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/fragment/MainFragment.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/fragment/MusicFragment.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/fragment/RecommendFragment.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/ui/fragment/VideoFragment.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/AdMultiView.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/CountdownTimeTextView.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/CustomRecyclerView.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/CustomRecyclerViewer.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/HomeMultiView.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/LoadingView.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/MultiView.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/MyLinearLayout.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/MyRelativeLayout.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/MyScrollView.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/MyTextView.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/SplashView.java create mode 100644 app/src/main/java/com/ik/mboxlauncher/view/TimeTextView.java create mode 100644 app/src/main/res/anim/anim_alpha_show.xml create mode 100644 app/src/main/res/drawable-hdpi/ic_launcher.png create mode 100644 app/src/main/res/drawable-ldpi/ic_launcher.png create mode 100644 app/src/main/res/drawable/app.png create mode 100644 app/src/main/res/drawable/app_border.xml create mode 100644 app/src/main/res/drawable/app_info_bg.xml create mode 100644 app/src/main/res/drawable/app_info_border.xml create mode 100644 app/src/main/res/drawable/app_item_bg.xml create mode 100644 app/src/main/res/drawable/app_item_border.xml create mode 100644 app/src/main/res/drawable/app_item_select.xml create mode 100644 app/src/main/res/drawable/bg.webp create mode 100644 app/src/main/res/drawable/frag_bg.webp create mode 100644 app/src/main/res/drawable/frame.9.png create mode 100644 app/src/main/res/drawable/img_chrome.webp create mode 100644 app/src/main/res/drawable/img_filemanager.webp create mode 100644 app/src/main/res/drawable/img_hbomax.webp create mode 100644 app/src/main/res/drawable/img_miracastreceive.webp create mode 100644 app/src/main/res/drawable/img_music.webp create mode 100644 app/src/main/res/drawable/img_netflix.webp create mode 100644 app/src/main/res/drawable/img_primevideo.webp create mode 100644 app/src/main/res/drawable/img_recommend.webp create mode 100644 app/src/main/res/drawable/img_setting.webp create mode 100644 app/src/main/res/drawable/img_status_ethernet.png create mode 100644 app/src/main/res/drawable/img_status_sdcard.png create mode 100644 app/src/main/res/drawable/img_status_usb.png create mode 100644 app/src/main/res/drawable/img_video.webp create mode 100644 app/src/main/res/drawable/img_youtube.webp create mode 100644 app/src/main/res/drawable/item_add_img.png create mode 100644 app/src/main/res/drawable/item_child_1.png create mode 100644 app/src/main/res/drawable/item_child_2.png create mode 100644 app/src/main/res/drawable/item_child_3.png create mode 100644 app/src/main/res/drawable/item_child_4.png create mode 100644 app/src/main/res/drawable/item_child_5.png create mode 100644 app/src/main/res/drawable/item_child_6.png create mode 100644 app/src/main/res/drawable/item_img_add.png create mode 100644 app/src/main/res/drawable/item_img_apps.png create mode 100644 app/src/main/res/drawable/item_img_sel.png create mode 100644 app/src/main/res/drawable/item_text_bg.xml create mode 100644 app/src/main/res/drawable/line.png create mode 100644 app/src/main/res/drawable/local.png create mode 100644 app/src/main/res/drawable/music.png create mode 100644 app/src/main/res/drawable/recommend.png create mode 100644 app/src/main/res/drawable/tab_apps_normal.png create mode 100644 app/src/main/res/drawable/tab_apps_select.png create mode 100644 app/src/main/res/drawable/tab_apps_selector.xml create mode 100644 app/src/main/res/drawable/tab_bg_selector.xml create mode 100644 app/src/main/res/drawable/tab_local_normal.png create mode 100644 app/src/main/res/drawable/tab_local_select.png create mode 100644 app/src/main/res/drawable/tab_local_selector.xml create mode 100644 app/src/main/res/drawable/tab_music_normal.png create mode 100644 app/src/main/res/drawable/tab_music_select.png create mode 100644 app/src/main/res/drawable/tab_music_selector.xml create mode 100644 app/src/main/res/drawable/tab_recommend_normal.png create mode 100644 app/src/main/res/drawable/tab_recommend_select.png create mode 100644 app/src/main/res/drawable/tab_recommend_selector.xml create mode 100644 app/src/main/res/drawable/tab_video_normal.png create mode 100644 app/src/main/res/drawable/tab_video_select.png create mode 100644 app/src/main/res/drawable/tab_video_selector.xml create mode 100644 app/src/main/res/drawable/video.png create mode 100644 app/src/main/res/drawable/wifi1.png create mode 100644 app/src/main/res/drawable/wifi2.png create mode 100644 app/src/main/res/drawable/wifi3.png create mode 100644 app/src/main/res/drawable/wifi4.png create mode 100644 app/src/main/res/drawable/wifi5.png create mode 100644 app/src/main/res/layout-sw480dp/ad_multi_layout.xml create mode 100644 app/src/main/res/layout-sw480dp/add_apps_grid_item.xml create mode 100644 app/src/main/res/layout-sw480dp/apps_grid_item.xml create mode 100644 app/src/main/res/layout-sw480dp/childgrid_item.xml create mode 100644 app/src/main/res/layout-sw480dp/homegrid_item.xml create mode 100644 app/src/main/res/layout-sw480dp/homelist_item.xml create mode 100644 app/src/main/res/layout-sw480dp/layout_category_app.xml create mode 100644 app/src/main/res/layout-sw480dp/layout_custom_apps1.xml create mode 100644 app/src/main/res/layout-sw480dp/layout_rect_group1.xml create mode 100644 app/src/main/res/layout-sw480dp/layout_shortcut.xml create mode 100644 app/src/main/res/layout-sw480dp/layout_statusbar.xml create mode 100644 app/src/main/res/layout-sw480dp/main.xml create mode 100644 app/src/main/res/layout-sw480dp/multi_layout.xml create mode 100644 app/src/main/res/layout-sw540dp/ad_multi_layout.xml create mode 100644 app/src/main/res/layout-sw540dp/add_apps_grid_item.xml create mode 100644 app/src/main/res/layout-sw540dp/apps_grid_item.xml create mode 100644 app/src/main/res/layout-sw540dp/childgrid_item.xml create mode 100644 app/src/main/res/layout-sw540dp/homegrid_item.xml create mode 100644 app/src/main/res/layout-sw540dp/homelist_item.xml create mode 100644 app/src/main/res/layout-sw540dp/layout_category_app.xml create mode 100644 app/src/main/res/layout-sw540dp/layout_custom_apps1.xml create mode 100644 app/src/main/res/layout-sw540dp/layout_rect_group1.xml create mode 100644 app/src/main/res/layout-sw540dp/layout_shortcut.xml create mode 100644 app/src/main/res/layout-sw540dp/layout_statusbar.xml create mode 100644 app/src/main/res/layout-sw540dp/main.xml create mode 100644 app/src/main/res/layout-sw540dp/multi_layout.xml create mode 100644 app/src/main/res/layout-sw720dp/ad_multi_layout.xml create mode 100644 app/src/main/res/layout-sw720dp/add_apps_grid_item.xml create mode 100644 app/src/main/res/layout-sw720dp/apps_grid_item.xml create mode 100644 app/src/main/res/layout-sw720dp/childgrid_item.xml create mode 100644 app/src/main/res/layout-sw720dp/homegrid_item.xml create mode 100644 app/src/main/res/layout-sw720dp/homelist_item.xml create mode 100644 app/src/main/res/layout-sw720dp/layout_category_app.xml create mode 100644 app/src/main/res/layout-sw720dp/layout_custom_apps1.xml create mode 100644 app/src/main/res/layout-sw720dp/layout_rect_group1.xml create mode 100644 app/src/main/res/layout-sw720dp/layout_shortcut.xml create mode 100644 app/src/main/res/layout-sw720dp/layout_statusbar.xml create mode 100644 app/src/main/res/layout-sw720dp/main.xml create mode 100644 app/src/main/res/layout-sw720dp/multi_layout.xml create mode 100644 app/src/main/res/layout/activity_my.xml create mode 100644 app/src/main/res/layout/activity_splash_screen.xml create mode 100644 app/src/main/res/layout/add_apps_grid_item.xml create mode 100644 app/src/main/res/layout/childgrid_item.xml create mode 100644 app/src/main/res/layout/homegrid_item.xml create mode 100644 app/src/main/res/layout/homelist_item.xml create mode 100644 app/src/main/res/layout/launcher_layout.xml create mode 100644 app/src/main/res/layout/layout_category_app.xml create mode 100644 app/src/main/res/layout/layout_custom_apps1.xml create mode 100644 app/src/main/res/layout/layout_rect_group1.xml create mode 100644 app/src/main/res/layout/layout_shortcut.xml create mode 100644 app/src/main/res/layout/layout_statusbar.xml create mode 100644 app/src/main/res/layout/main.xml create mode 100644 app/src/main/res/layout/multi_layout.xml create mode 100644 app/src/main/res/raw/default_shortcut.shortcut create mode 100644 app/src/main/res/values-ar/arrays.xml create mode 100644 app/src/main/res/values-ar/strings.xml create mode 100644 app/src/main/res/values-es/arrays.xml create mode 100644 app/src/main/res/values-es/strings.xml create mode 100644 app/src/main/res/values-pt/arrays.xml create mode 100644 app/src/main/res/values-pt/strings.xml create mode 100644 app/src/main/res/values-zh-rCN/arrays.xml create mode 100644 app/src/main/res/values-zh-rCN/strings.xml create mode 100644 app/src/main/res/values-zh-rTW/arrays.xml create mode 100644 app/src/main/res/values-zh-rTW/strings.xml create mode 100644 app/src/main/res/values/arrays.xml create mode 100644 app/src/main/res/values/attrs.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/main/res/xml/sharefile.xml create mode 100644 app/src/test/java/com/ik/mboxlauncher/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 mylibrary/.gitignore create mode 100644 mylibrary/build.gradle create mode 100644 mylibrary/consumer-rules.pro create mode 100644 mylibrary/proguard-rules.pro create mode 100644 mylibrary/src/androidTest/java/com/android/ExampleInstrumentedTest.java create mode 100644 mylibrary/src/main/AndroidManifest.xml create mode 100644 mylibrary/src/main/java/com/android/MXQConfig.java create mode 100644 mylibrary/src/main/java/com/android/api/ServerApi.java create mode 100644 mylibrary/src/main/java/com/android/api/ServerInterface.java create mode 100644 mylibrary/src/main/java/com/android/api/biz/BaseBiz.java create mode 100644 mylibrary/src/main/java/com/android/api/biz/Biz.java create mode 100644 mylibrary/src/main/java/com/android/api/biz/CoreKeys.java create mode 100644 mylibrary/src/main/java/com/android/api/biz/OnBaseListener.java create mode 100644 mylibrary/src/main/java/com/android/api/biz/bizimpl/BizImpl.java create mode 100644 mylibrary/src/main/java/com/android/api/encrytion/AESUtil.java create mode 100644 mylibrary/src/main/java/com/android/api/encrytion/MD5Utils.java create mode 100644 mylibrary/src/main/java/com/android/api/encrytion/TimeUtil.java create mode 100644 mylibrary/src/main/java/com/android/api/encrytion/UtilEncrypt.java create mode 100644 mylibrary/src/main/java/com/android/api/encrytion/UtilHex.java create mode 100644 mylibrary/src/main/java/com/android/api/response/BaseResponse.java create mode 100644 mylibrary/src/main/java/com/android/api/response/EventResponse.java create mode 100644 mylibrary/src/main/java/com/android/database/AbstractDaoMannager.java create mode 100644 mylibrary/src/main/java/com/android/database/DaoManager.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/AdsInfoBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/AppBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/AppConfigBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/AppMonitorBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/DownLoadTaskBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/EventBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/GoogleADEvent.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/LocalAppBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/MusicAppBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/NetShortAppBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/RecommendAppBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/RecordEventBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/ShortAppBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/TaskInfoBean.java create mode 100644 mylibrary/src/main/java/com/android/database/lib/VideoAppBean.java create mode 100644 mylibrary/src/main/java/com/android/device/MediaStateChangeObserver.java create mode 100644 mylibrary/src/main/java/com/android/device/MediaStateChangeReceiver.java create mode 100644 mylibrary/src/main/java/com/android/device/NetStateChangeObserver.java create mode 100644 mylibrary/src/main/java/com/android/device/NetStateChangeReceiver.java create mode 100644 mylibrary/src/main/java/com/android/download/AppExecutors.java create mode 100644 mylibrary/src/main/java/com/android/download/DownLoadManeger.java create mode 100644 mylibrary/src/main/java/com/android/download/DownLoadTaskThread.java create mode 100644 mylibrary/src/main/java/com/android/download/DownloadAppTask.java create mode 100644 mylibrary/src/main/java/com/android/download/DownloadService.java create mode 100644 mylibrary/src/main/java/com/android/download/TaskQueue.java create mode 100644 mylibrary/src/main/java/com/android/eventbaus/EventBusUtils.java create mode 100644 mylibrary/src/main/java/com/android/eventbaus/MessageEvent.java create mode 100644 mylibrary/src/main/java/com/android/monitor/DataBeeObserver.java create mode 100644 mylibrary/src/main/java/com/android/monitor/MonitorManager.java create mode 100644 mylibrary/src/main/java/com/android/monitor/MonitorThread.java create mode 100644 mylibrary/src/main/java/com/android/monitor/impl/EventFactory.java create mode 100644 mylibrary/src/main/java/com/android/monitor/impl/EventInterface.java create mode 100644 mylibrary/src/main/java/com/android/monitor/impl/GoogleEventImpl.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/ADManager.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/AppManager.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/TaskManager.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/bean/ADInfo.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/bean/ADInfoResponse.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/bean/BaseBean.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/bean/BaseEvent.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/bean/BaseValue.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/bean/EventDataInfo.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/bean/EventResponse.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/bean/FavNaviBean.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/presenter/AppnetPresenter.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/presenter/CategoryAppPresenter.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/presenter/DataBeePresenter.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/presenter/callback/AppnetCallback.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/presenter/callback/BaseCallback.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/presenter/callback/BlackListCallback.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/presenter/callback/CategoryAppCallback.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/presenter/callback/NetCallback.java create mode 100644 mylibrary/src/main/java/com/android/nebulasdk/presenter/callback/StatisticsCallback.java create mode 100644 mylibrary/src/main/java/com/android/util/AppInstallUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/BitmapUtils.java create mode 100644 mylibrary/src/main/java/com/android/util/DateUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/DeviceUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/EventBusType.java create mode 100644 mylibrary/src/main/java/com/android/util/FileSystem.java create mode 100644 mylibrary/src/main/java/com/android/util/FileUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/GetEditionCode.java create mode 100644 mylibrary/src/main/java/com/android/util/GsonUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/IntentUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/LogManager.java create mode 100644 mylibrary/src/main/java/com/android/util/LogUtils.java create mode 100644 mylibrary/src/main/java/com/android/util/MaxLengthWatcher.java create mode 100644 mylibrary/src/main/java/com/android/util/MimeType.java create mode 100644 mylibrary/src/main/java/com/android/util/NetUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/NetworkType.java create mode 100644 mylibrary/src/main/java/com/android/util/NetworkUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/PakageInstallUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/RKDeviceUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/SharedPreferencesUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/StringUtil.java create mode 100644 mylibrary/src/main/java/com/android/util/SystemBarTintManager.java create mode 100644 mylibrary/src/test/java/com/android/ExampleUnitTest.java create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..90b510d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build +.gradle +.idea +./local.properties diff --git a/README.md b/README.md new file mode 100644 index 0000000..71e180c --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +#MXQLauncher diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..cc5fbe4 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1,5 @@ +build +.gradle +.idea +local.properties +release \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..853ba4b --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,108 @@ +apply plugin: 'com.android.application' + +static def getManufacturer(){ + return 'rockchip' +} +android { + namespace 'com.ik.mboxlauncher' + compileSdk 34 + defaultConfig { + applicationId "com.droidlogic.mboxlauncher" + minSdkVersion 21 + targetSdkVersion 34 + multiDexEnabled true + versionCode 568888804 + versionName "SNFLauncher-5.6.4" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + buildConfigField "String", "MANUFACTURER", '"rockchip"' + buildConfigField "boolean", "LOG_ENABLED", "false" + buildConfigField "int", "NETWORK_TIMEOUT", "30" + buildConfigField "double", "PI_VALUE", "3.1415926535" + } +// RK方案 版本名3.5.0,版本号 3588880 +// Allwinner方案 版本名5.5.0,版本号 5588880 + + signingConfigs { + release { + storeFile file("../app/platform_rk.keystore") + storePassword 'android' + keyAlias 'platform' + keyPassword 'android' + } + + debug { + storeFile file("../app/platform_rk.keystore") + storePassword 'android' + keyAlias 'platform' + keyPassword 'android' + } + } + buildTypes { + release { + minifyEnabled false + // shrinkResources true + // 启用代码压缩(配合混淆,但此处可单独用于删除未使用类) + // minifyEnabled true + // 配置混淆文件(即使不混淆,也可用于定义保留规则) + // 启用Zipalign优化 + // zipAlignEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.release + } + debug { + signingConfig signingConfigs.debug + } + } + + applicationVariants.all { variant -> + variant.outputs.all { + outputFileName = "app-${variant.buildType.name}-${variant.versionName}-${getManufacturer()}-${variant.versionCode}-${new Date().format('yyyyMMddHHmm')}.apk" + } + } + + buildFeatures{ + aidl = true + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + lintOptions { + checkReleaseBuilds false + abortOnError false + } + sourceSets { + main { + aidl { + srcDirs 'src/main/aidl' + } + } + } + buildFeatures { + buildConfig true + } + +} + +dependencies { + implementation fileTree(dir:"libs", includes:["*.aar"]) + implementation 'com.github.bumptech.glide:glide:3.6.1' + implementation project(':mylibrary') + def media3_version = "1.3.1" + implementation "androidx.media3:media3-ui:$media3_version" + implementation "androidx.media3:media3-exoplayer:$media3_version" + + // The library adds the IMA ExoPlayer integration for ads. + implementation "androidx.media3:media3-exoplayer-ima:$media3_version" + + implementation 'androidx.multidex:multidex:2.0.1' + implementation 'com.google.android.material:material:1.9.0' + + //消息组件 + implementation 'org.greenrobot:eventbus:3.1.1' + + implementation 'com.google.android.gms:play-services-ads:20.3.0' + + +} \ No newline at end of file diff --git a/app/libs/SAD-release-1.0.9.aar b/app/libs/SAD-release-1.0.9.aar new file mode 100644 index 0000000000000000000000000000000000000000..77339b727bd3280fe080c44b2c2ad5ee4c992bce GIT binary patch literal 63812 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

|n7jQqb)ur)ezcDH5q?qZ@5*H>8g~fuR0C% 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 literal 0 HcmV?d00001 diff --git a/app/platform_rk.keystore b/app/platform_rk.keystore new file mode 100644 index 0000000000000000000000000000000000000000..900f84d191ef2b5bbf92a3ec52df1605157df4a5 GIT binary patch literal 2376 zcmd6o_fwPU7RU1@AtZqy5Jaj}BSqj1gn%^ZUFp&h5L`+UvUCI@grd@60TEfMh%}{I z06~gk7m;2KRX`Mxl@f%Dd-vYEGxz=h_lGmjoXEs^0?7v;k&eD-1%a?YKstOEC`Ele8W?OihZ3r&W?3@@*(yH^IR1{bz(AI#?!c8Ld5cm_NRoLXT1>MmKD@f3(p!K zcq>#&ERlQHjz`_*yz@%)>TBXki>9o~GJP_t7?_q{CtlwuW*g{i+?kY~){(4nptK>% z&La8eXBLl##f@gavyct@)ulpWELVNFS~xEA6EYmXv!u5^;n%F?Lt9>!>`K=|%xj5D z`S{82lGShZ*@cwvlxT1^F^f0vn;8x#yx;3_K2yCAo$ixwGD3vbW>XJ!eYnIS)hCe@ zKZxspuW=NAkM1#dSBwMWl=y_5WaPZ6Ys7m)!#L|L*`Pw$M}_Wfe%#C1{cFn8y@0}t zlJEia?U(LlY}p;i!01CZ+fwFZ3Q33OO-{7%nro#P{}3H8jnludxMAk{4xJ-gsIk~b z99+m{i zc$`UzR_i6{H}|asXUeDgqr*q+(pLPY?lTSiztmmtAYCYDy6{T-{|13}fs)_58CoQ;eRr?M88qkKCjt!{)vz zn}=6=s86?)Mjp27tA&ZQ;6-w_be9yNVtH2~YN)JJs7VCuedYlqQ>) zfh4Bg!gFErj>V46ij1QP?IqtK<=jv`(SUv2y}Vx^Hm!}7s)mG323FqXJsszxVs_R2 zN75JSgaI-oNn%y^vH`AU#AXv*Ve31)f5a&}tnV5$%V~tqjebCfEHrAIX|5 znRRT?0*QYVs#a)yv6E+lb~|9~zVG+(mo&lDz953P>2_!k(-OizmGP^k4@+Tem)fpN zgyWq#FC3tenr{tFoERS<3)<*5IqkJp3}4mRnNx%a?Hpae<8?4=bg4SWHK{~~_@|0K zn;I^aA1aJnonnt_cCV!+XLN_jw8d&})ID_+Vgw44?yCqRJy6?)8OrEs=qW_QG$8_4 z6mPZQ=GMM1W>vXvc5$p!iu~To?=s@|s4V)6kRrjrd4yZwldyPC3PosdNG)Wuao~#j zo#)=OqYu5yddksjk;gdo7~Qe-#yb3^ANl;Wkr)P!gJx`mD|qE0?Ch^?ijrFGxq+N1 z#(mcg{616ZNA8cJY7&p_4RurP=Sj*;t)S|d_*3n5`c=D`>kDtB5uV(aDn%1>nsMTc z64u*&$0W-5E29ybwf2IfAR;33;f|H2d#$MGW;Ww@>AKKaW{GdLv5Vbu)&zg-8S4UM z_4eR#V=dw1#!W3-Tkz$F4R3(z;xssFKG8QMRq-jW>{fosNQ(E zL-7g>@b&r^Vf!xv`wtNZMgKhm3gE?h{PVB&U$6Z605W*=2nJ8UD=I31M1m3l?{ox1 zPz06n;9u$g>)3Qa^zQ;6oFEt-z#QBr012f70HkDO%`x1yU;7++U1TdK&8Jr*dns-SxH8%)lsGr6*9`;ZWd~f2gWF;G|_S`QcStuT&RHo zmh&Qud!X30D9Mi;lh$jmY&wn#EL#(c(A(0|szdAXIH6{x1qvY-kL5F7)+?5Wq4L9R z_gImCU<~u(mRe!N^5Yj`nnLXR>{ks;pa87Q5qqBfj-O@R|LPX#$;m zDAg7p?sfAm8Wj0imVontyfOc~f&FI#7R~~~0AT;`iXW`>f#LwfXh@ecNA$caR$gZ) zPC?fHYwlH-xDX+<`zS=ipUCMl*TL#m+(oHn*$N5nP&?7V?6&Yx>L2ZRQrFC$KvdHF z%Y@@kb7O>sY8_Tl=7CzE$h97r}weQSH=JoI1cdO=7S86$J5XYc4F{`-L6=h>v zW$GY3?-2SmK= IjpV>T0KpRVUjP6A literal 0 HcmV?d00001 diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..68d977d --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,74 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile + +-keep class com.seraphic.ad.** { *; } +-keep interface com.seraphic.ad.** { *; } +-keepclassmembers class com.seraphic.ad.** { *; } +# ========== R 类保留 ========== +#-keep class **.R +#-keep class **.R$* { +# ; +#} +# +## ========== 基本组件保留 ========== +#-keep public class * extends android.app.Activity +#-keep public class * extends android.app.Application +#-keep public class * extends android.app.Service +#-keep public class * extends android.content.BroadcastReceiver +#-keep public class * extends android.content.ContentProvider +# +## ========== GreenDAO 配置 ========== +## 保留 GreenDAO 核心库 +#-keep class org.greenrobot.greendao.** { *; } +#-dontwarn org.greenrobot.greendao.** +# +## 保留子程序中的实体类(请根据实际情况修改包名) +#-keep class com.android.nebulasdk.bean.** { *; } +#-keep class com.android.api.response.**{*;} +# +## ========== 其他第三方库 ========== +## Glide +#-keep public class * implements com.bumptech.glide.module.GlideModule +# +## EventBus +#-keepattributes *Annotation* +#-keepclassmembers class * { +# @org.greenrobot.eventbus.Subscribe ; +#} +# +## Retrofit +#-keepattributes Signature, InnerClasses, EnclosingMethod +#-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations +#-keepclassmembers,allowshrinking,allowobfuscation interface * { +# @retrofit2.http.* ; +#} +# +## Media3 +#-keep class androidx.media3.** { *; } +#-dontwarn androidx.media3.** +# +## Google Ads +#-keep class com.google.android.gms.ads.** { *; } +#-dontwarn com.google.android.gms.ads.** +# +#-dontwarn org.conscrypt.Conscrypt +#-dontwarn org.conscrypt.OpenSSLProvider \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..be245d6 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/ik/download/DownLoadAppListener.java b/app/src/main/java/com/ik/download/DownLoadAppListener.java new file mode 100644 index 0000000..af10a14 --- /dev/null +++ b/app/src/main/java/com/ik/download/DownLoadAppListener.java @@ -0,0 +1,5 @@ +package com.ik.download; + +public interface DownLoadAppListener { + void onDowanlaodResult(int msg,String path); +} diff --git a/app/src/main/java/com/ik/download/DownloadAppTask.java b/app/src/main/java/com/ik/download/DownloadAppTask.java new file mode 100644 index 0000000..9a2e6b2 --- /dev/null +++ b/app/src/main/java/com/ik/download/DownloadAppTask.java @@ -0,0 +1,127 @@ +package com.ik.download; + +import android.content.Context; + + +import com.android.util.FileUtil; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URL; + +public class DownloadAppTask extends Thread{ + private String downurl; + private Context mContext; + /**存储路径*/ + private String FILEPATH_STORAGE; + /**临时文件名称*/ + private static String FILENAME_TMP="launcher.bak"; + /**正是文件名称*/ + private static String FILENAME_APK="launcher.apk"; + private DownLoadAppListener mDownLoadAppListener; + private long startIndex = 0; + private long totalSize = 0; + + public DownloadAppTask(Context context,String url,long fileSize,DownLoadAppListener downLoadAppListener){ + mContext = context; + this.downurl = url; + this.totalSize = fileSize; + this.mDownLoadAppListener = downLoadAppListener; + this.FILEPATH_STORAGE = FileUtil.getBakPath(mContext,1) ; + } + + @Override + public void run() { + super.run(); + try { + File tempfile =new File(FILEPATH_STORAGE,FILENAME_TMP); + if(tempfile.exists()){ + startIndex = tempfile.length(); + }else { + tempfile.createNewFile(); + } + HttpURLConnection urlConnection; + URL url = new URL(downurl); + urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.setConnectTimeout(2000*10); //设置连接超时事件为5秒 + urlConnection.setRequestMethod("GET"); //设置请求方式为GET + //设置用户端可以接收的媒体类型 + urlConnection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, " + + "image/pjpeg, application/x-shockwave-flash, application/xaml+xml, " + + "application/vnd.ms-xpsdocument, application/x-ms-xbap," + + " application/x-ms-application, application/vnd.ms-excel," + + " application/vnd.ms-powerpoint, application/msword, */*"); + + urlConnection.setRequestProperty("Accept-Language", "zh-CN"); //设置用户语言 + urlConnection.setRequestProperty("Charset", "UTF-8"); //设置客户端编码 + //设置用户代理 + urlConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; " + + "Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727;" + + " .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"); + //设置下载位置 + urlConnection.setRequestProperty("Range", "bytes=" + startIndex + "-" + totalSize); + InputStream in = urlConnection.getInputStream(); + RandomAccessFile raf = new RandomAccessFile(tempfile.getPath(), "rwd"); + raf.seek(startIndex); + int len = 0; + byte buf[] =new byte[1024]; + while((len = in.read(buf))!=-1){ + raf.write(buf, 0, len); + } + in.close(); + raf.close(); + File apkFile = new File(FILEPATH_STORAGE,FILENAME_APK); + if(tempfile.length()==totalSize){ + tempfile.renameTo(apkFile); + tempfile.delete(); +// executeAppInstall(FILEPATH_STORAGE+"/"+FILENAME_APK); + if(mDownLoadAppListener!=null){ + mDownLoadAppListener.onDowanlaodResult(0,apkFile.getPath()); + } + }else { + if(mDownLoadAppListener!=null){ + mDownLoadAppListener.onDowanlaodResult(-1,null); + } + } + + } catch (Exception e) { + e.printStackTrace(); + if(mDownLoadAppListener!=null){ + mDownLoadAppListener.onDowanlaodResult(-1,null); + } + } + + + + + } + + + + public boolean executeAppInstall(String apkPath){ + boolean result = false; + try { + Runtime.getRuntime().exec("su"); + String command = "pm install -r " + apkPath + "\n"; + Process process = Runtime.getRuntime().exec(command); + BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String msg = ""; + String line; + while ((line = errorStream.readLine()) != null) { + msg += line; + } + if (!msg.contains("Failure")) { + result = true; + } + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + +} diff --git a/app/src/main/java/com/ik/download/DownloadImgTask.java b/app/src/main/java/com/ik/download/DownloadImgTask.java new file mode 100644 index 0000000..23aa65d --- /dev/null +++ b/app/src/main/java/com/ik/download/DownloadImgTask.java @@ -0,0 +1,101 @@ +package com.ik.download; + +import android.content.Context; +import android.content.SharedPreferences; + + +import com.android.util.FileUtil; + +import java.io.File; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.net.HttpURLConnection; +import java.net.URL; + +public class DownloadImgTask extends Thread{ + private String downurl; + private Context mContext; + private String FILEPATH_STORAGE; + private String name; + private String[] baks = {"0.bak","1.bak","2.bak","3.bak","4.bak"}; + public static String[] imgs = {"bcg","video","f_video","recomm","f_recomm"}; + private long startIndex = 0; + private long totalSize = 0; + private static int Count = 0; + private int mIndex = 0; + + private SharedPreferences mSharedPreferences; + public DownloadImgTask(Context context, String url, long fileSize,int index,SharedPreferences sharedPreferences,String name,ReconnNetIMG reconnNetIMG){ + mContext = context; + this.downurl = url; + this.totalSize = fileSize; + this.FILEPATH_STORAGE = FileUtil.getBakPath(mContext,0) ; + this.mIndex = index; + this.mSharedPreferences = sharedPreferences; + this.name = name; + this.mReconnNetIMG = reconnNetIMG; + } + + @Override + public void run() { + super.run(); + try { + int len = 0; + File tempfile =new File(FILEPATH_STORAGE,baks[mIndex]); + if(tempfile.exists()){ + startIndex = tempfile.length(); + }else { + tempfile.createNewFile(); + } + HttpURLConnection urlConnection; + URL url = new URL(downurl); + urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.setConnectTimeout(2000*10); //设置连接超时事件为5秒 + urlConnection.setRequestMethod("GET"); //设置请求方式为GET + urlConnection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, " + + "image/pjpeg, application/x-shockwave-flash, application/xaml+xml, " + + "application/vnd.ms-xpsdocument, application/x-ms-xbap," + + " application/x-ms-application, application/vnd.ms-excel," + + " application/vnd.ms-powerpoint, application/msword, */*"); + + urlConnection.setRequestProperty("Accept-Language", "zh-CN"); //设置用户语言 + urlConnection.setRequestProperty("Charset", "UTF-8"); //设置客户端编码 + urlConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; " + + "Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727;" + + " .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"); + urlConnection.setRequestProperty("Range", "bytes=" + startIndex + "-" + totalSize); + InputStream in = urlConnection.getInputStream(); + RandomAccessFile raf = new RandomAccessFile(tempfile.getPath(), "rwd"); + raf.seek(startIndex); + byte buf[] =new byte[1024]; + while((len = in.read(buf))!=-1){ + raf.write(buf, 0, len); + } + in.close(); + raf.close(); +// Log.i("==========","============"+totalSize); + if(tempfile.length()==totalSize){ + String tmp = FileUtil.getBakPath(mContext,0)+"/"+mSharedPreferences.getString(DownloadImgTask.imgs[mIndex], "0.png"); + File tmpFile1 = new File(tmp); + if(tmpFile1.exists()){ + tmpFile1.delete(); + } + File apkFile = new File(FILEPATH_STORAGE, name); + mSharedPreferences.edit().putString(imgs[mIndex],name).apply(); + tempfile.renameTo(apkFile); + tempfile.delete(); + Count++; + if(mReconnNetIMG!=null){ + mReconnNetIMG.LoadIMG(Count); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public ReconnNetIMG mReconnNetIMG; + interface ReconnNetIMG{ + void LoadIMG(int c); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/SystemService.java b/app/src/main/java/com/ik/mboxlauncher/SystemService.java new file mode 100644 index 0000000..365a757 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/SystemService.java @@ -0,0 +1,372 @@ +package com.ik.mboxlauncher; + +import android.app.Service; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.PowerManager; +import android.preference.PreferenceManager; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + +import com.android.device.NetStateChangeReceiver; +import com.android.eventbaus.EventBusUtils; +import com.android.eventbaus.MessageEvent; +import com.android.nebulasdk.ADManager; +import com.android.device.NetStateChangeObserver; +import com.android.nebulasdk.bean.ADInfo; +import com.android.nebulasdk.presenter.AppnetPresenter; +import com.android.nebulasdk.presenter.callback.AppnetCallback; +import com.android.util.LogUtils; +import com.android.util.NetUtil; +import com.android.util.NetworkType; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +/** + * 资源同步后台服务 + * 功能: + * 1. 首次执行无条件请求接口(不检查时间) + * 2. 首次成功执行后,必须等待8小时才能再次请求 + * 3. 仅在请求成功时记录时间,失败不记录 + * 4. 设备重启后重置为首次请求状态 + */ +public class SystemService extends Service implements AppnetCallback, NetStateChangeObserver { + + private static final int WHAT_REQUEST_ADMSG = 0; + private static final int WHAT_NETWORK_CHANGE = 3; + private static final int WHAT_PERIODIC_REQUEST = 4; + + // 请求间隔(8小时,正式环境) + // private static final long REQUEST_INTERVAL = 8 * 60 * 60 * 1000; + // 测试用短间隔 + private static final long REQUEST_INTERVAL = 5 * 60 * 1000; // 5分钟 + //持久化存储成功请求时间 + private static final String KEY_LAST_SUCCESS_TIME = "last_success_time"; + private boolean isFirstRequestDone = false; // 首次请求是否完成(重启后重置为false) + private boolean isRunning = false; + private boolean isRequesting = false; + + private AppnetPresenter appnetPresenter; + private Handler handler; + private SharedPreferences sharedPreferences; + private PowerManager powerManager; + + @Override + public void onCreate() { + super.onCreate(); + if (!isRunning) { + isRunning = true; + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + powerManager = (PowerManager) getSystemService(POWER_SERVICE); + initHandler(); + + NetStateChangeReceiver.registerReceiver(this); + NetStateChangeReceiver.registerObserver(this); + + // 检查是否是重启后首次启动服务 + checkRebootStatus(); + + // 检查网络并执行首次请求 + checkNetworkAndInitiateFirstRequest(); + + //handler.postDelayed(() -> ADManager.getInstance().restDownloadTask(), 3000); + } + } + + /** + * 检查是否是重启后首次启动 + */ + private void checkRebootStatus() { + if (powerManager != null) { + // 判断是否是开机后首次启动服务 + boolean isReboot = powerManager.isInteractive(); + if (isReboot) { + // LogUtils.loge("检测到设备重启,重置为首次请求状态"); + isFirstRequestDone = false; + } + } + } + + private void initHandler() { + handler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(@NonNull Message msg) { + switch (msg.what) { + case WHAT_REQUEST_ADMSG: + handleAdRequest(); + break; + case WHAT_NETWORK_CHANGE: + notifyNetworkChange(); + break; + case WHAT_PERIODIC_REQUEST: + handlePeriodicRequest(); + break; + } + } + }; + } + + private void handlePeriodicRequest() { +// boolean should=shouldRequestImmediately(); +// LogUtils.loge("shouldRequestImmediately()="+should+"isRequesting="+isRequesting); + if (isNetworkAvailable() && shouldRequestImmediately() && !isRequesting) { + LogUtils.loge("定时任务:满足条件,执行请求,task turn on"); + handleAdRequest(); + } else { + scheduleNextPeriodicRequest(); + } + } + + private void checkNetworkAndInitiateFirstRequest() { + if (isFirstRequestDone) { + if (shouldRequestImmediately() && !isRequesting) { + handler.sendEmptyMessage(WHAT_REQUEST_ADMSG); + } else { + LogUtils.loge("首次请求已完成,启动定时任务 first request"); + scheduleNextPeriodicRequest(); + } + return; + } + + boolean currentNetworkAvailable = isNetworkAvailable(); + if (currentNetworkAvailable && !isRequesting) { + LogUtils.loge("执行首次请求 first request handler msg"); + handler.sendEmptyMessage(WHAT_REQUEST_ADMSG); + } else { + LogUtils.loge("网络不可用,安排首次请求检查 network dont work"); + scheduleNextPeriodicRequest(); + } + } + + private void scheduleNextPeriodicRequest() { + handler.removeMessages(WHAT_PERIODIC_REQUEST); + + if (!isFirstRequestDone) { + LogUtils.loge("首次请求未完成,5分钟后再次检查 first uncompletely"); + handler.sendEmptyMessageDelayed(WHAT_PERIODIC_REQUEST, 5*60 * 1000); + return; + } + + long lastSuccessTime = getLastSuccessTime(); + long currentTime = System.currentTimeMillis(); + + // 从未成功过,使用检查间隔 + if (lastSuccessTime == 0) { + LogUtils.loge("从未成功请求过,1个小时后再次尝试,no success,1hour later try"); + handler.sendEmptyMessageDelayed(WHAT_PERIODIC_REQUEST, 60 * 60 * 1000); + return; + } + + long nextRequestTime = lastSuccessTime + REQUEST_INTERVAL; + long delay = Math.max(0, nextRequestTime - currentTime); + LogUtils.loge("delay="+delay); + handler.sendEmptyMessageDelayed(WHAT_PERIODIC_REQUEST, delay); +// if (isNetworkAvailable()){ +// LogUtils.loge("定时任务安排完成:" + +// "上次成功时间=" + formatTime(lastSuccessTime) + +// ",当前时间=" + formatTime(currentTime) + +// ",延迟=" + (delay / 1000 / 60) + "分钟" + +// ",下次执行=" + formatTime(currentTime + delay)); +// } + } + + private boolean shouldRequestImmediately() { + if (!isFirstRequestDone) { + return true; + } + + long lastSuccessTime = getLastSuccessTime(); + long currentTime = System.currentTimeMillis(); + + if (lastSuccessTime == 0) { + LogUtils.loge("从未成功请求过,应立即请求 unsuccess task turn on"); + return true; + } + if (currentTime < lastSuccessTime) { + LogUtils.loge("满足(时间回退),应立即请求 time forecase task turn on"); + return true; + } + long timeDiff = currentTime - lastSuccessTime; + + if (timeDiff >= REQUEST_INTERVAL) { + LogUtils.loge("满足8小时间隔条件,应立即请求 delay 8 hour task turn on"); + return true; + } + + LogUtils.loge("不满足8小时间隔条件,不应请求 undelay 8 hour task turn off"); + return false; + } + + private void markFirstRequestDone() { + isFirstRequestDone = true; + // LogUtils.loge("标记首次请求已完成"); + } + + private void handleAdRequest() { + if (isRequesting) { + return; + } + + if (appnetPresenter == null) { + try { + appnetPresenter = new AppnetPresenter(this); + } catch (Exception e) { + isRequesting = false; + if (!isFirstRequestDone) { + markFirstRequestDone(); + } + // 失败时不保存时间 + // saveLastSuccessTime(); + LogUtils.loge("请求异常 request exception"); + scheduleNextPeriodicRequest(); + return; + } + } + + isRequesting = true; + appnetPresenter.postLauncherAds(this); + } + + private void notifyNetworkChange() { + EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_MEDIA_STATUS)); + } + + private boolean isNetworkAvailable() { + int netState = NetUtil.getNetWorkState(this); + return netState == NetUtil.NETWORK_MOBILE + || netState == NetUtil.NETWORK_WIFI + || netState == NetUtil.NETWORK_ETHERNET; + } + + private long getLastSuccessTime() { + return sharedPreferences.getLong(KEY_LAST_SUCCESS_TIME, 0); + } + + private void saveLastSuccessTime() { + long currentTime = System.currentTimeMillis(); + sharedPreferences.edit() + .putLong(KEY_LAST_SUCCESS_TIME, currentTime) + .apply(); + LogUtils.loge("已保存本次成功请求时间:refresh" + formatTime(currentTime)); + } + + @Override + public void onNetDisconnected() { + LogUtils.loge("网络断开 netdisconnect"); + handler.sendEmptyMessage(WHAT_NETWORK_CHANGE); + } + + @RequiresApi(api = Build.VERSION_CODES.O) + @Override + public void onNetConnected(NetworkType networkType) { + LogUtils.loge("网络连接恢复:netconnect" + networkType.name()); + scheduleNextPeriodicRequest(); + handler.sendEmptyMessage(WHAT_NETWORK_CHANGE); + } + + @Override + public void onResult(Object data) { + isRequesting = false; + List adInfoList = (data instanceof List) ? (List) data : new ArrayList<>(); + ADManager.getInstance().updateADInfo(adInfoList); + + if (!isFirstRequestDone) { + markFirstRequestDone(); + } + + // 成功时保存时间 + saveLastSuccessTime(); + + scheduleNextPeriodicRequest(); + } + + @Override + public void onViewFailureString(int code, String message) { + isRequesting = false; + LogUtils.loge("接口请求失败(视图层):错误码= code" + code + ",错误信息= viewmsg" + message); + handleRequestFailure(); + } + + @Override + public void onExceptionFailure(String message) { + isRequesting = false; + LogUtils.loge("接口请求异常:异常信息= exceptionmsg" + message); + handleRequestFailure(); + } + + @Override + public void onServerFailure(int code, String message) { + isRequesting = false; + LogUtils.loge("接口请求失败(服务端):错误码= code" + code + ",错误信息= servermsg" + message); + // handleRequestFailure(); + // 仅保留首次请求完成标记(必须保留,避免无限重复首次请求) + if (!isFirstRequestDone) { + markFirstRequestDone(); + } + boolean isTimeout = code==0 || message.contains("The server is busy"); + if (isTimeout) { + handler.removeMessages(WHAT_PERIODIC_REQUEST); + handler.sendEmptyMessageDelayed(WHAT_PERIODIC_REQUEST, REQUEST_INTERVAL); + } else { + //保留原逻辑 + scheduleNextPeriodicRequest(); + } + } + + private void handleRequestFailure() { + if (!isFirstRequestDone) { + markFirstRequestDone(); + } + + // 失败时不保存时间 + // saveLastSuccessTime(); + scheduleNextPeriodicRequest(); + } + + @RequiresApi(api = Build.VERSION_CODES.O) + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return START_STICKY; + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public void onDestroy() { + super.onDestroy(); + isRunning = false; + isRequesting = false; + + NetStateChangeReceiver.unRegisterObserver(this); + NetStateChangeReceiver.unRegisterReceiver(this); + + if (handler != null) { + handler.removeCallbacksAndMessages(null); + } + + if (appnetPresenter != null) { + appnetPresenter = null; + } + } + + private String formatTime(long timestamp) { + if (timestamp == 0) return "未记录 no record"; + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault()); + sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); + return sdf.format(new Date(timestamp)); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/VersionBean.java b/app/src/main/java/com/ik/mboxlauncher/VersionBean.java new file mode 100644 index 0000000..15343e7 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/VersionBean.java @@ -0,0 +1,25 @@ +package com.ik.mboxlauncher; + +public class VersionBean { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } + + private int version; + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/receiver/LauncherReceiverFromOther.java b/app/src/main/java/com/ik/mboxlauncher/receiver/LauncherReceiverFromOther.java new file mode 100644 index 0000000..3c2eee8 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/receiver/LauncherReceiverFromOther.java @@ -0,0 +1,30 @@ +package com.ik.mboxlauncher.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import com.ik.mboxlauncher.ui.OnRefresnLauncherListener; + +public class LauncherReceiverFromOther extends BroadcastReceiver { + public static final String LAUNCHER_UPDATE="com.ik.launcher.res.notify"; + public static final String ADVERT_UPDATE="com.ik.Advert.res.notify"; + static OnRefresnLauncherListener mOnRefresnLauncherListener; + public static void setOnRefresnLauncherListener(OnRefresnLauncherListener onRefresnLauncherListener){ + mOnRefresnLauncherListener = onRefresnLauncherListener; + } + + @Override + public void onReceive(Context context, Intent intent) { + if(intent.getAction().equals(LAUNCHER_UPDATE)){ + if(mOnRefresnLauncherListener!=null){ + mOnRefresnLauncherListener.refreshLauncher(); + } + }else { + if(mOnRefresnLauncherListener!=null){ + mOnRefresnLauncherListener.refreshAdversh(); + } + } + } + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/ADSWindowManager.java b/app/src/main/java/com/ik/mboxlauncher/ui/ADSWindowManager.java new file mode 100644 index 0000000..d9a3260 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/ADSWindowManager.java @@ -0,0 +1,200 @@ +package com.ik.mboxlauncher.ui; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Handler; + +import androidx.media3.common.Player; + +import com.android.database.lib.AdsInfoBean; +import com.android.monitor.DataBeeObserver; +import com.android.monitor.impl.EventFactory; +import com.android.nebulasdk.ADManager; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.view.AdMultiView; +import com.ik.mboxlauncher.view.MultiView; +import com.ik.mboxlauncher.view.HomeMultiView; +import com.seraphic.ad.AdStateListener; + +import java.io.File; +import java.util.List; + +public class ADSWindowManager implements HomeMultiView.MultiViewListener{ + + private List mMultiViewList; + private List mAdsInfoBeanList; + /**当前video广告播放索引*/ + private int currentADIndex=0; + private Context mContext; + private static ADSWindowManager mInstance = null; + private Handler mHandler= new Handler(); + + /**广告延迟播放时间*/ +// private static final long DELAYED_TIME=1000*60*5; + private static final long DELAYED_TIME=1000*60*1; + + /**是否开启播放模式*/ + private boolean isPlayMode=false; + + + private ADSWindowManager(Context context){ + this.mContext =context; + } + + public static void init(Context context){ + if(mInstance==null){ + mInstance = new ADSWindowManager(context); + } + + } + + public static ADSWindowManager getInstance(){ + return mInstance; + } + + + /**绑定数据源*/ + public void bindSourceData(List multiViewList, List adsInfoBeanList){ + this.mMultiViewList=multiViewList; + this.mAdsInfoBeanList = adsInfoBeanList; + if(mMultiViewList.size()>mAdsInfoBeanList.size()){ + LogUtils.loge("数据源绑定不一致,mAdsInfoBeanList size is "+mMultiViewList.size()+" adsInfoBeanList size is "+adsInfoBeanList.size()); + } + + for (MultiView multiView:mMultiViewList){ + multiView.setMultiViewListener(this); + } + + } + public void startVideo(){ + isPlayMode =true; + LogUtils.loge("currentADIndex|mMultiViewList.size()==="+currentADIndex+"|"+mMultiViewList.size()); + if(currentADIndex= mMultiViewList.size()) { //所有文件都不存在,跳出循环,都不播放 + currentADIndex=0; + } + startVideo(); + + } + + } + + @Override + public void onPlaybackStateChanged(int viewId, int playbackState) { +// if(playbackState== Player.STATE_BUFFERING){ +// if(currentADIndex= mMultiViewList.size()) { + currentADIndex = 0; + } + delayedStartVideo(); + }else { + LogUtils.loge("PlayMode is pause"); + } + + } + } + + + + + private Runnable runnable = new Runnable() { + @Override + public void run() { + if(mMultiViewList!=null&¤tADIndex SCREEN_HEIGHT/2) { +// if (top+3-CustomAppsActivity.CONTENT_HEIGHT > 0) { +// screenShot = Bitmap.createBitmap(bmp, 0, 0,bmp.getWidth(), top); +// screenShot_keep = Bitmap.createBitmap(bmp, 0, CustomAppsActivity.CONTENT_HEIGHT, +// bmp.getWidth(), top +3-CustomAppsActivity.CONTENT_HEIGHT); +// } else { +// screenShot = Bitmap.createBitmap(bmp, 0, 0,bmp.getWidth(), CustomAppsActivity.CONTENT_HEIGHT); +// screenShot_keep = null; +// } +// } else { +// screenShot = Bitmap.createBitmap(bmp, 0, bottom,bmp.getWidth(), SCREEN_HEIGHT-bottom); +// screenShot_keep = Bitmap.createBitmap(bmp, 0, bottom, +// bmp.getWidth(), SCREEN_HEIGHT-(bottom+CustomAppsActivity.CONTENT_HEIGHT)); +// } +// } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + + LogUtils.loge("onKeyDown===>"+keyCode); + + if(keyCode==KeyEvent.KEYCODE_BACK){ + if(currentFragment.onKeyDown(keyCode,event)){ + return true; + }else { + return super.onKeyDown(keyCode,event); + } + } + return super.onKeyDown(keyCode,event); + + } + + + + + MediaStateChangeObserver mediaStateChangeObserver = new MediaStateChangeObserver() { + @Override + public void onMediaRecever(String action) { + + if(currentFragment!=null){ + currentFragment.onResumeFragment(new MessageEvent(action)); + } + + } + }; + + + @Override + public void finish() { + super.finish(); + setResult(0); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/FragmentManager.java b/app/src/main/java/com/ik/mboxlauncher/ui/FragmentManager.java new file mode 100644 index 0000000..b3366de --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/FragmentManager.java @@ -0,0 +1,87 @@ +package com.ik.mboxlauncher.ui; + +import android.content.Context; + +import com.ik.mboxlauncher.ui.base.BaseFragment; +import com.ik.mboxlauncher.ui.base.NotifyInterface; +import com.ik.mboxlauncher.ui.fragment.AppsFragment; +import com.ik.mboxlauncher.ui.fragment.LocalFragment; +import com.ik.mboxlauncher.ui.fragment.MainFragment; +import com.ik.mboxlauncher.ui.fragment.MusicFragment; +import com.ik.mboxlauncher.ui.fragment.RecommendFragment; +import com.ik.mboxlauncher.ui.fragment.VideoFragment; + + +/** + * 存放所有Livetv Fragment + */ +public class FragmentManager { + + private Context mContext; + private static FragmentManager mInstance = null; + + /*主菜单*/ + public static final int MAIN_TAG=0x00; + /*all apps*/ + public static final int APPS_TAG=0x01; + /*music apps*/ + public static final int MUSIC_APPS_TAG=0x02; + /*music apps*/ + public static final int RECOMMEND_APPS_TAG=0x03; + public static final int VIDEO_APPS_TAG=0x04; + public static final int LOCAL_APPS_TAG=0x05; + private AppsFragment mAppsFragment; + private LocalFragment mLocalFragment; + private MainFragment mMainFragment; + private MusicFragment mMusicFragment; + private RecommendFragment mRecommendFragment; + private VideoFragment mVideoFragment; + + private FragmentManager(Context context, NotifyInterface notifyInterface){ + this.mContext = context; + mAppsFragment = new AppsFragment(); + mAppsFragment.setNotifyInterface(notifyInterface); + mLocalFragment = new LocalFragment(); + mLocalFragment.setNotifyInterface(notifyInterface); + mMainFragment = new MainFragment(); + mMainFragment.setNotifyInterface(notifyInterface); + mMusicFragment = new MusicFragment(); + mMusicFragment.setNotifyInterface(notifyInterface); + mRecommendFragment = new RecommendFragment(); + mRecommendFragment.setNotifyInterface(notifyInterface); + mVideoFragment = new VideoFragment(); + mVideoFragment.setNotifyInterface(notifyInterface); + } + + public static void init(Context context, NotifyInterface notifyInterface){ + if(mInstance==null){ + mInstance = new FragmentManager(context,notifyInterface); + } + + } + + public static FragmentManager getInstance(){ + return mInstance; + } + + public BaseFragment getFragmentByTag(int tagStr){ + switch (tagStr){ + case MAIN_TAG: + return mMainFragment; + case APPS_TAG: + return mAppsFragment; + case MUSIC_APPS_TAG: + return mMusicFragment; + case RECOMMEND_APPS_TAG: + return mRecommendFragment; + case VIDEO_APPS_TAG: + return mVideoFragment; + case LOCAL_APPS_TAG: + return mLocalFragment; + } + return null; + } + public void destory(){ + mInstance = null; + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/Launcher.java b/app/src/main/java/com/ik/mboxlauncher/ui/Launcher.java new file mode 100644 index 0000000..33c0f03 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/Launcher.java @@ -0,0 +1,978 @@ +package com.ik.mboxlauncher.ui; + +import android.annotation.SuppressLint; +import android.app.Fragment; +import android.content.ComponentName; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.PixelFormat; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.util.ArrayMap; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.Display; +import android.view.Gravity; +import android.view.InputDevice; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.animation.Animation; +import android.view.animation.TranslateAnimation; +import android.widget.GridView; +import android.widget.Toast; + +import androidx.media3.common.Player; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; + +import com.android.MXQConfig; +import com.android.api.encrytion.UtilEncrypt; +import com.android.database.lib.AdsInfoBean; +import com.android.database.lib.AppBean; +import com.android.database.lib.ShortAppBean; +import com.android.device.MediaStateChangeObserver; +import com.android.device.MediaStateChangeReceiver; +import com.android.eventbaus.MessageEvent; +import com.android.monitor.DataBeeObserver; +import com.android.nebulasdk.ADManager; +import com.android.nebulasdk.AppManager; +import com.android.nebulasdk.bean.FavNaviBean; +import com.android.util.GsonUtil; +import com.android.util.IntentUtil; +import com.android.util.LogUtils; +import com.android.util.PakageInstallUtil; +import com.ik.mboxlauncher.R; +import com.ik.mboxlauncher.ui.adapter.CustomAppAdapter; +import com.ik.mboxlauncher.ui.adapter.ShortAppInfoAdapter; +import com.ik.mboxlauncher.ui.adapter.StatusAdapter; +import com.ik.mboxlauncher.ui.base.FragmentActivity; +import com.ik.mboxlauncher.ui.base.StatusLoader; +import com.ik.mboxlauncher.ui.fragment.AppsFragment; +import com.ik.mboxlauncher.ui.fragment.MusicFragment; +import com.ik.mboxlauncher.ui.fragment.RecommendFragment; +import com.ik.mboxlauncher.ui.fragment.VideoFragment; +import com.ik.mboxlauncher.view.MultiView; +import com.ik.mboxlauncher.view.AdMultiView; +import com.ik.mboxlauncher.view.CustomRecyclerView; +import com.ik.mboxlauncher.view.SplashView; +import com.ik.mboxlauncher.view.TimeTextView; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 主界面 + */ +public class Launcher extends FragmentActivity implements SplashView.SplashAdListener { + public static final String TAG="com.ik.mboxlauncher.ui.fragment.MainFragment"; + private MultiView layout_video,layout_music,layout_primevideo,layout_filemanager,layout_hbomax,layout_setting,layout_youtube,layout_recommend,layout_netflix,layout_chrome; + private AdMultiView layout_miracastreceive; + private int[] imageResIds={R.drawable.img_video,R.drawable.img_miracastreceive,R.drawable.img_youtube,R.drawable.img_recommend,R.drawable.img_music,R.drawable.img_netflix,R.drawable.img_primevideo,R.drawable.img_filemanager,R.drawable.img_chrome,R.drawable.img_hbomax,R.drawable.img_setting}; + private CustomRecyclerView gv_shortcut,grid_coustom_apps; + private StatusLoader mStatusLoader; + private ShortAppInfoAdapter mShortAppInfoAdapter=null; + private CustomAppAdapter mCustomAppAdapter=null; + private StatusAdapter ad =null; + + private GridView lv_status; + private TimeTextView tx_time; + private View content_view,coustom_view; + private MultiView[] multiViewArray = new MultiView[imageResIds.length]; + protected static final int MODEL_NORMAL = 0x00; + protected static final int MODEL_CUSTOM = 0x01; + protected int cuttentModel=MODEL_NORMAL; + + public static int SCREEN_HEIGHT; + public static int SCREEN_WIDTH; + public static Bitmap screenShot; + public static Bitmap screenShot_keep; + private Handler handler = new Handler(); + private int mHomeHeight; + private View shortcut_layout; + + private ViewGroup ad_full_root; + + /**闪屏界面是否结束*/ + private boolean isSplashEnd=false; + private SplashView mSplashView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + LogUtils.loge("onCreate===>"); + Log.e("liu", "Launcher run ad: "+System.currentTimeMillis() ); + if(mSplashView==null){ + mSplashView = new SplashView(Launcher.this); + mSplashView.setmSplashAdListener(this); + mSplashView.show(); + } +// startActivity(new Intent(Launcher.this,SplashscreenActivity.class)); + Display display = getWindowManager().getDefaultDisplay(); + DisplayMetrics displayMetrics = new DisplayMetrics(); + display.getRealMetrics(displayMetrics); + int screenWidth = displayMetrics.widthPixels; + int screenHeight = displayMetrics.heightPixels; + LogUtils.loge("screenWidth|screenHeight=====>"+screenWidth+"|"+screenHeight+"|"+displayMetrics.densityDpi); +// LogManager.init(Launcher.this); +// AppManager.init(Launcher.this); +// ADManager.init(Launcher.this); +// LogUtils.loge("onCreate 11111==>"); +// Intent startIntent = new Intent(this, SystemService.class); +//// bindService(startIntent,connection,Context.BIND_AUTO_CREATE); +// startService(startIntent); + MediaStateChangeReceiver.registerReceiver(this); + StartupBroadcast.registerReceiver(this); +// MediaStateChangeReceiver.registerObserver(mediaStateChangeObserver); + + + + super.onCreate(savedInstanceState); + + } + + @Override + protected int getlayoutId() { + return R.layout.main; + } + + @Override + protected void initView() { + LogUtils.loge("initView===>"); + mStatusLoader = new StatusLoader(this); + layout_video = findViewById(R.id.layout_video); + layout_video.setOnClickListener(onClickListener); + multiViewArray[0]=layout_video; + ad_full_root = findViewById(R.id.ad_full_root); + layout_miracastreceive = findViewById(R.id.layout_miracastreceive); + layout_miracastreceive.setOnClickListener(onClickListener); + layout_miracastreceive.setFullRooView(ad_full_root); + multiViewArray[1]=layout_miracastreceive; + layout_youtube = findViewById(R.id.layout_youtube); + layout_youtube.setOnClickListener(onClickListener); +// layout_youtube.setFullRooView(ad_full_root); + multiViewArray[2]=layout_youtube; + layout_recommend = findViewById(R.id.layout_recommend); + layout_recommend.setOnClickListener(onClickListener); +// layout_recommend.setFullRooView(ad_full_root); + multiViewArray[3]=layout_recommend; + layout_music = findViewById(R.id.layout_music); + layout_music.setOnClickListener(onClickListener); + multiViewArray[4]=layout_music; + layout_netflix = findViewById(R.id.layout_netflix); + layout_netflix.setOnClickListener(onClickListener); +// layout_netflix.setFullRooView(ad_full_root); + multiViewArray[5]=layout_netflix; + layout_primevideo = findViewById(R.id.layout_primevideo); + layout_primevideo.setOnClickListener(onClickListener); + multiViewArray[6]=layout_primevideo; + layout_filemanager = findViewById(R.id.layout_filemanager); + layout_filemanager.setOnClickListener(onClickListener); + multiViewArray[7]=layout_filemanager; + layout_chrome = findViewById(R.id.layout_chrome); + layout_chrome.setOnClickListener(onClickListener); +// layout_chrome.setFullRooView(ad_full_root); + multiViewArray[8]=layout_chrome; + layout_hbomax = findViewById(R.id.layout_hbomax); + layout_hbomax.setOnClickListener(onClickListener); + multiViewArray[9]=layout_hbomax; + layout_setting = findViewById(R.id.layout_setting); + layout_setting.setOnClickListener(onClickListener); + multiViewArray[10]=layout_setting; + gv_shortcut = findViewById(R.id.gv_shortcut); + lv_status = findViewById(R.id.list_status); + tx_time = findViewById(R.id.tx_time); + grid_coustom_apps = findViewById(R.id.grid_coustom_apps); + content_view = findViewById(R.id.content_view); + coustom_view= findViewById(R.id.coustom_view); + shortcut_layout = findViewById(R.id.shortcut_layout); + + + + + if(mShortAppInfoAdapter==null){ + mShortAppInfoAdapter = new ShortAppInfoAdapter(this); + mShortAppInfoAdapter.setmOnSelectItemListener(new ShortAppInfoAdapter.OnSelectItemListener() { + @Override + public void onSelectItem(ShortAppBean shortAppInfoBean, int selectIndex) { + if(shortAppInfoBean.getItemType()==0){ + LogUtils.loge("open app custom view"); + if(selectIndex == 0){ + gotoAction(AppsFragment.ACTION); + } else { + if (!isShowCustomApp()) { + showCustomApps(); + } + } + + }else { + LogUtils.loge("open app package name is "+shortAppInfoBean.getPackageName()); + IntentUtil.startApp(Launcher.this,shortAppInfoBean.getPackageName(),getResources().getString(R.string.app_not_exist)); + } + } + }); + } + if(mCustomAppAdapter==null){ + mCustomAppAdapter = new CustomAppAdapter(this,AppManager.CATEGORY_SHORT); + mCustomAppAdapter.setmOnSelectItemListener(new CustomAppAdapter.OnSelectItemListener() { + @Override + public void onSelectItem(AppBean shortAppInfoBean, int sleectIndex) { + if(shortAppInfoBean.getItemType()==0){ + if(!isShowCustomApp()) { + showCustomApps(); + } + }else { + LogUtils.loge("open app, package is "+shortAppInfoBean.getPackageName()+"|"+mCustomAppAdapter.getItemCount()); +// if(mCustomAppAdapter.getItemCount()<9) { + if (shortAppInfoBean.getSelect() == 0) { + if(mCustomAppAdapter.countSelectApp()"+childViewPosition); + if(childViewPosition==-1){//当焦点错乱是,强制修正找到目标位置(例如第一个可见项) + int[] rows=new int[8]; + ((StaggeredGridLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPositions(rows); + View targetView = recyclerView.findViewHolderForAdapterPosition(rows[0]).itemView; + targetView.post(() -> targetView.requestFocus()); + } + + } + } + }); + + ADSWindowManager.init(this); + bindAdsWindowMultiView(); + } + + + + + + @Override + protected void onResume() { + super.onResume(); + // 当网络发生变化,判断当前网络状态,并通过NetEvent回调当前网络状态 +// if (netWorkState == NetUtil.NETWORK_MOBILE || netWorkState == NetUtil.NETWORK_WIFI || netWorkState == NetUtil.NETWORK_ETHERNET) { + + LogUtils.loge("onResume"); + displayStatus(); + handler.post(runnable); +// handler.removeCallbacks(runnable); +// handler.postDelayed(runnable,1000*60*5); + + +// setImageViewData(); +// LogUtils.loge("有可用网络"); +// } else { +// LogUtils.loge("没有可用网络"); +// } + + mHomeHeight = findViewById(R.id.layout_homepage).getHeight(); + } + + @Override + protected void initData() { + tx_time.starTimeUi(); + displayStatus(); + loadShortAppList(); + + + } + + @Override + protected int getFramlayoutId() { + return R.layout.main; + } + + @Override + protected Fragment onCreateInitialFragment() { + return null; + } + + + @SuppressLint("UnsafeOptInUsageError") + private void setImageViewData(){ + for (int i=0;i adInfoList = ADManager.getInstance().getADInfoListByadType(ADManager.ADTYPE_IMAGE); +// LogUtils.loge("adInfoList===>"+adInfoList.size()); +// int i=0; +// for (AdsInfoBean adInfo:adInfoList ) { +// +// +// +// +// +// +// +//// if (adInfo != null) { +//// LogUtils.loge(i+" adInfo.getAppUrl()==>"+adInfo.getAppUrl()); +//// LogUtils.loge(i+" adInfo.getInfo()==>"+adInfo.getInfo()); +//// LogUtils.loge(i+" adInfo.getAdUri()==>"+adInfo.getAdUri()); +//// +//// if (adInfo.getAppUrl() != null && adInfo.getInfo() != null) { +//// if (PakageInstallUtil.checkAppInstall(Launcher.this, adInfo.getInfo(), adInfo.getAppVersion())) { //已安装了以后才可以显示图片 +//// multiView.onImageRestartLocal(adInfo.getLocalFilePath()); +//// LogUtils.loge(adInfo.getInfo()+" is installed"); +//// }else { +//// LogUtils.loge(adInfo.getInfo()+" is not installed"); +//// } +//// }else { +//// String iconPath=null; +//// //TODO 设置默认图标 +//// if(i==0){ +//// iconPath=AppManager.getInstance().getIconAssertData(AppManager.ICON_00_TAG); +//// +//// }else if(i==1){ +//// iconPath=AppManager.getInstance().getIconAssertData(AppManager.ICON_01_TAG); +//// }else if(i==2){ +//// iconPath=AppManager.getInstance().getIconAssertData(AppManager.ICON_02_TAG); +//// }else if(i==3){ +//// iconPath=AppManager.getInstance().getIconAssertData(AppManager.ICON_03_TAG); +//// }else if(i==4){ +//// iconPath=AppManager.getInstance().getIconAssertData(AppManager.ICON_04_TAG); +//// } +//// if(iconPath!=null&&!"".equals(iconPath)){ +//// multiView.onImageRestartLocal(iconPath); +//// }else { +//// LogUtils.loge("区域:"+i+"--未设置默认图片"); +//// } +//// } +//// +//// } +// +//// i++; +// } + + } + + + +// private void loadShortAppList(){ +// +// runOnUiThread(new Runnable() { +// @Override +// public void run() { +// List shortcutInfoBeanList = AppManager.getInstance().getShortAppBeanAppByCategory(); +// mShortAppInfoAdapter.addDatas(shortcutInfoBeanList); +// } +// }); +// +// } +private void loadShortAppList(){ + runOnUiThread(() -> { + List shortcutInfoBeanList = AppManager.getInstance().getShortAppBeanAppByCategory(); + LogUtils.loge("显示的recycleView:"+ GsonUtil.GsonString(shortcutInfoBeanList)); + // 创建过滤后的列表 + List filteredList = new ArrayList<>(); + String selfPackageName = getPackageName(); + + for (ShortAppBean appBean : shortcutInfoBeanList) { + // 跳过自身应用 + if (appBean.getPackageName().equals(selfPackageName) || appBean.getPackageName().equals("com.android.traceur")) { + LogUtils.loge("排除自己和com.android.traceur:" + appBean.getPackageName()); + continue; // 不添加到过滤列表 + } + // 添加非自身应用 + filteredList.add(appBean); + } + + mShortAppInfoAdapter.addDatas(filteredList); + }); + +} + + +// private void loadCustomAppList(){ +// +// runOnUiThread(new Runnable() { +// @Override +// public void run() { +// List shortcutInfoBeanList = AppManager.getInstance().getmyAppByCategory(); +// LogUtils.loge("myapp "+shortcutInfoBeanList.size()); +// sortAppList(shortcutInfoBeanList); +// if(shortcutInfoBeanList!=null) { +// mCustomAppAdapter.addDatas((List)shortcutInfoBeanList); +// grid_coustom_apps.setAdapter(mCustomAppAdapter); +// }else { +// LogUtils.loge("no data"); +// } +// } +// }); +// +// } + + private void loadCustomAppList(){ + + runOnUiThread(new Runnable() { + @Override + public void run() { + List shortcutInfoBeanList = AppManager.getInstance().getmyAppByCategory(); + LogUtils.loge("myapp "+shortcutInfoBeanList.size()); + List filteredList = new ArrayList<>(); + String selfPackageName = getPackageName(); + for (AppBean appBean : shortcutInfoBeanList) { + // 跳过自身应用 + if (appBean.getPackageName().equals(selfPackageName) || appBean.getPackageName().equals("com.android.traceur")) { + LogUtils.loge("排除自己和com.android.traceur:" + appBean.getPackageName()); + continue; // 不添加到过滤列表 + } + // 添加非自身应用 + filteredList.add(appBean); + } + sortAppList(filteredList); + mCustomAppAdapter.addDatas(filteredList); + grid_coustom_apps.setAdapter(mCustomAppAdapter); + } + }); + + } + + + + private void sortAppList( List shortcutInfoBeanList){ + List shortAppBeanList = AppManager.getInstance().getShortAppBeanAppByCategory(); + Map tmpMapData = new HashMap<>(); + + for (ShortAppBean shortAppBean:shortAppBeanList){ + tmpMapData.put(shortAppBean.getPackageName(),shortAppBean); + } + + for (int i=0;i"+event.action); + if(MessageEvent.ACTION_UPADATE_DATA_SOURCE.equals(event.action)) { + ADManager.getInstance().updateDownloadTaskBeanTable(); + handler.removeCallbacks(runnable); + handler.postDelayed(runnable,1000*5); + + }else if(MessageEvent.ACTION_UPADATE_MEDIA_STATUS.equals(event.action)){ + displayStatus(); + }else if(MessageEvent.ACTION_UPADATE_APPS_SOURCE.equals(event.action)){ + if(currentFragment!=null&¤tFragment instanceof AppsFragment){ + currentFragment.onResumeFragment(event); + } + + } + + } + + private void displayStatus() { + + runOnUiThread(new Runnable() { + @Override + public void run() { + List> datas = mStatusLoader.getStatusData(); + if(ad==null){ + ad = new StatusAdapter(Launcher.this, datas, R.layout.homelist_item, + new String[] {StatusLoader.ICON}, + new int[] {R.id.item_type, 0, 0}); + lv_status.setAdapter(ad); + }else { + ad.addDatas(datas); + } + } + }); + + } + + + + private View.OnClickListener onClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { +// ADSWindowManager.getInstance().stopVideo(); + + MultiView multiView = (MultiView) v; + if(!multiView.onAdViewClick()){ + FavNaviBean favNaviBean = (FavNaviBean) v.getTag(); + + LogUtils.loge(GsonUtil.GsonString(favNaviBean)); + if(favNaviBean!=null){ + LogUtils.loge("go to app:"+favNaviBean.getRelatedApp()); + gotoActivity(favNaviBean.getRelatedApp()); + + }else { + if (v.getId() == R.id.layout_video) { + LogUtils.loge("go to video"); + gotoAction(VideoFragment.ACTION); + } else if (v.getId() == R.id.layout_youtube) { + LogUtils.loge("go to youtube"); + gotoActivity("com.google.android.youtube.tv"); + } else if (v.getId() == R.id.layout_recommend) { + LogUtils.loge("go to recommend"); + gotoAction(RecommendFragment.ACTION); + } else if (v.getId() == R.id.layout_music) { + LogUtils.loge("go to music"); + gotoAction(MusicFragment.ACTION); + } else if (v.getId() == R.id.layout_netflix) { + LogUtils.loge("go to netflix"); + gotoActivity("com.netflix.mediaclient"); + } else if (v.getId() == R.id.layout_primevideo) { + LogUtils.loge("go to primevideo"); +// gotoAction(LocalFragment.ACTION); + gotoActivity("com.amazon.amazonvideo.livingroom"); + } else if (v.getId() == R.id.layout_filemanager) { + LogUtils.loge("go to filemanager"); + if(MXQConfig.RK_PLATFORM.equalsIgnoreCase(MXQConfig.getManufacturer())){ + gotoFileManager(); + }else { + gotoActivity("com.softwinner.TvdFileManager"); + } + //gotoFileManager(); + } else if (v.getId() == R.id.layout_chrome) { + LogUtils.loge("go to chrome"); + gotoActivity("com.android.chrome"); + } else if (v.getId() == R.id.layout_hbomax) { + LogUtils.loge("go to hbomax"); + gotoActivity("com.wbd.stream"); + } else if (v.getId() == R.id.layout_setting) { + LogUtils.loge("go to setting"); + Intent intent = new Intent(); + if(MXQConfig.RK_PLATFORM.equalsIgnoreCase(MXQConfig.getManufacturer())) { + intent.setComponent(new ComponentName("com.android.tv.settings", "com.android.tv.settings.MainSettings")); + }else { + if (PakageInstallUtil.checkAppInstall(Launcher.this, "com.android.settings")) { + intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings")); + } else { + intent.setComponent(new ComponentName("com.android.tv.settings", "com.android.tv.settings.MainSettings")); + } + } + startActivity(intent); + + }else if (v.getId() == R.id.layout_miracastreceive) { + if(!layout_miracastreceive.onAdViewClick()){ + if(MXQConfig.RK_PLATFORM.equalsIgnoreCase(MXQConfig.getManufacturer())) { + gotoActivity("com.rockchip.wfd"); + }else { + gotoActivity("com.softwinner.miracastReceiver"); + } + } + } + } + + }else { + LogUtils.loge("go to Ad show"); + } + } + }; + + + private void gotoAction(String action){ + Intent intent = new Intent(Launcher.this,CategoryActivity.class); + Bundle bundle = new Bundle(); + bundle.putString("action",action); + intent.putExtras(bundle); + startActivity(intent); + } + + + private void gotoActivity(String packageName){ + if (PakageInstallUtil.checkAppInstall(Launcher.this, packageName)) { //已安装了以后才可以显示图片 + IntentUtil.startApp(Launcher.this,packageName,getResources().getString(R.string.app_not_exist)); + LogUtils.loge(packageName+" is installed"); + }else { + Toast.makeText( Launcher.this, getResources().getString(R.string.app_not_exist), Toast.LENGTH_SHORT).show(); + LogUtils.loge(packageName+" is not installed"); + } + } + + + + private void gotoFileManager(){ + if (PakageInstallUtil.checkAppInstall(Launcher.this, "com.android.rockchip")) { //已安装了以后才可以显示图片 + IntentUtil.startApp(Launcher.this,"com.android.rockchip",getResources().getString(R.string.app_not_exist)); + LogUtils.loge("com.android.rockchip is installed"); + }else if(PakageInstallUtil.checkAppInstall(Launcher.this, "com.rockchips.mediacenter")){ + IntentUtil.startApp(Launcher.this,"com.rockchips.mediacenter",getResources().getString(R.string.app_not_exist)); + }else if(PakageInstallUtil.checkAppInstall(Launcher.this, "com.estrongs.android.pop")){ + IntentUtil.startApp(Launcher.this,"com.estrongs.android.pop",getResources().getString(R.string.app_not_exist)); + }else { + Toast.makeText( Launcher.this, getResources().getString(R.string.app_not_exist), Toast.LENGTH_SHORT).show(); + LogUtils.loge("com.android.rockchip is not installed"); + } + } + + + private void showCustomApps(){ + cuttentModel = MODEL_CUSTOM; + LogUtils.loge("coustom_view.getHeight():"+coustom_view.getLayoutParams().height); + TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f,0.0f, (float)(0 - coustom_view.getLayoutParams().height-gv_shortcut.getHeight())); + translateAnimation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + content_view.clearFocus(); + loadCustomAppList(); + coustom_view.setVisibility(View.VISIBLE); + } + + @Override + public void onAnimationEnd(Animation animation) { + gv_shortcut.clearFocus(); + gv_shortcut.setFocusable(false); + coustom_view.setTranslationZ(5); + coustom_view.requestFocus(); + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + }); + translateAnimation.setDuration(300); + translateAnimation.setFillAfter(true); + content_view.startAnimation(translateAnimation); + +// TranslateAnimation exitTransAnim = new TranslateAnimation(0.0f, 0.0f,coustom_view.getY()+coustom_view.getLayoutParams().height, 0); +// exitTransAnim.setDuration(300); +// translateAnimation.setFillAfter(true); +// coustom_view.startAnimation(exitTransAnim); +// coustom_view.setTranslationZ(5); +// coustom_view.setVisibility(View.VISIBLE); + } + + + private void dismissCustomApp(){ + cuttentModel = MODEL_NORMAL; + LogUtils.loge("coustom_view.getHeight():"+coustom_view.getLayoutParams().height); + TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f,(float)(0 - coustom_view.getLayoutParams().height - gv_shortcut.getHeight()),0.0f); + translateAnimation.setDuration(300); + translateAnimation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + coustom_view.setTranslationZ(0); + loadShortAppList(); + coustom_view.clearFocus(); + } + + @Override + public void onAnimationEnd(Animation animation) { + coustom_view.setVisibility(View.GONE); + gv_shortcut.requestFocus(); + + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + }); + translateAnimation.setFillAfter(true); + content_view.startAnimation(translateAnimation); +// TranslateAnimation exitTransAnim = new TranslateAnimation(0.0f, 0.0f, 0,coustom_view.getY()+coustom_view.getLayoutParams().height); +// exitTransAnim.setDuration(300); +// translateAnimation.setFillAfter(true); +// coustom_view.startAnimation(exitTransAnim); + } + + private boolean isShowCustomApp(){ + return cuttentModel==MODEL_NORMAL?false:true; + } + + + + + protected void selectAppByCategory(AppBean appBean,int Category){ + AppManager.getInstance().selectAppByCategory(appBean,Category); + + } + + + + Player.Listener mediaListener = new Player.Listener() { + @Override + public void onPlaybackStateChanged(int playbackState) { + LogUtils.loge("onPlaybackStateChanged:"+playbackState); + + if(playbackState == Player.STATE_ENDED){ + + + } + + } + }; + + + /*** + * 创建有资源可播放的广告窗口 + * @return + */ + private void bindAdsWindowMultiView(){ + List adsInfoBeanList= ADManager.getInstance().getADInfoListByadType(ADManager.ADTYPE_VIDEO); + List multiViewArrayList = new ArrayList<>(); + List adsDatas=new ArrayList<>(); + for (int i=0;i"); + handler.removeCallbacks(runnable); + ADSWindowManager.getInstance().stopVideo(); + } + + + @Override + public void finish() { + super.finish(); + MediaStateChangeReceiver.unRegisterReceiver(this); + StartupBroadcast.unRegisterReceiver(this); + } + + Runnable runnable = new Runnable() { + @Override + public void run() { + LogUtils.loge("UI runnable....."); + LogUtils.loge("代码更新了"); + bindAdsWindowMultiView(); + if(isSplashEnd) { + ADSWindowManager.getInstance().startVideo(); + } + ADManager.getInstance().clearTaskInteruptQueueAndRestart(); + setImageViewData(); + loadShortAppList(); + } + }; + + + + + + + + + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + } + + + @Override + public void onEnd() { + isSplashEnd =true; +// ADSWindowManager.getInstance().startVideo(); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/MyActivity.java b/app/src/main/java/com/ik/mboxlauncher/ui/MyActivity.java new file mode 100644 index 0000000..b4374c9 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/MyActivity.java @@ -0,0 +1,64 @@ +package com.ik.mboxlauncher.ui; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.os.Bundle; +import android.os.Handler; +import android.view.View; + +import com.ik.mboxlauncher.R; +import com.ik.mboxlauncher.view.LoadingView; +import com.ik.mboxlauncher.view.HomeMultiView; + +/** Main Activity. */ +@SuppressLint("UnsafeOptInUsageError") +/* @SuppressLint is needed for new media3 APIs. */ +public class MyActivity extends Activity { + + private HomeMultiView ad_splash_view; + private Handler handler =new Handler(); + private float startAngle=180f; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_my); + LoadingView loadingView =findViewById(R.id.loading_view); + + findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + } + }); + ad_splash_view = findViewById(R.id.ad_splash_view); + +// ad_splash_view.setMultiViewListener(new MultiView.MultiViewListener() { +// @Override +// public void onPlaybackStateChanged(int viewId, int playbackState) { +// +// if(playbackState== Player.STATE_ENDED||playbackState==Player.STATE_IDLE){ +// +// } +// }}); +// +// String filePath ="/storage/emulated/0/Android/data/com.droidlogic.mboxlauncher/cache/ADVERT/53624c4f-8e53-479e-9736-e030957745fb.mp4"; +// File file = new File(filePath); +// if(file.exists()){ +// ad_splash_view.onVideoRestart(file.getPath()); +// +// +// } + + + + + +// handler.postDelayed(new Runnable() { +// @Override +// public void run() { +// +// } +// },1000*10); + + } + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/MyApplication.java b/app/src/main/java/com/ik/mboxlauncher/ui/MyApplication.java new file mode 100644 index 0000000..1dee3a5 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/MyApplication.java @@ -0,0 +1,107 @@ +package com.ik.mboxlauncher.ui; + +import android.app.Application; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import com.android.monitor.DataBeeObserver; +import com.android.nebulasdk.ADManager; +import com.android.nebulasdk.AppManager; +import com.android.util.LogManager; +import com.android.util.LogUtils; +import com.google.android.gms.ads.identifier.AdvertisingIdClient; +import com.ik.mboxlauncher.SystemService; +import com.seraphic.ad.AdConfig; +import com.seraphic.ad.AdManager; + +import java.io.PrintWriter; +import java.io.StringWriter; + +public class MyApplication extends Application { + + @Override + public void onCreate() { + super.onCreate(); + LogManager.init(getApplicationContext()); + DataBeeObserver.init(getApplicationContext()); + AppManager.init(getApplicationContext()); + ADManager.init(getApplicationContext()); + + AdConfig config = new AdConfig.Builder() + .isDebug(false)//是否开始 debug 模式,开启会打印更多log,供开发调试 + .productName("aike")//正式发版时使用正式的PN + .productTag("launcher")//正式发版时使用正式的PT +// .productName("test")//仅限开发测试使用 +// .productTag("test")//仅限开发测试使用 + .adId(getAdId(this)) + .build(); + AdManager.getInstance().init(MyApplication.this, config); + Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread thread, Throwable throwable) { + // 记录异常信息(如日志、上传到服务器等) + logCrash(throwable); + + // 可选:重启应用或结束进程 + restartApp(); + android.os.Process.killProcess(android.os.Process.myPid()); + } + }); + + + + new Thread(){ + + @Override + public void run() { + super.run(); + AppManager.getInstance().initLocalConfigData(); + AppManager.getInstance().initApplications(); + try { + + // sleep(1000*60); + sleep(1000*30); + Intent startIntent = new Intent(getApplicationContext(), SystemService.class); + startService(startIntent); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + + } + }.start(); + + } + + private String getAdId(Context context) { + AdvertisingIdClient.Info adInfo = null; + try { + adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context); + return adInfo.getId(); // 获取Advertising ID + } catch (Exception e) { + return null; + } + } + + + private void logCrash(Throwable throwable) { + // 将异常信息写入文件或上传到服务器 + StringWriter sw = new StringWriter(); + throwable.printStackTrace(new PrintWriter(sw)); + String exceptionDetails = sw.toString(); + LogUtils.loge("logCrash: "+exceptionDetails); + + // 示例:保存到本地文件 +// saveToFile(exceptionDetails); + + // 示例:上传到 Firebase Crashlytics +// FirebaseCrashlytics.getInstance().recordException(throwable); + } + + private void restartApp() { + Intent intent = new Intent(this, Launcher.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/OnRefresnLauncherListener.java b/app/src/main/java/com/ik/mboxlauncher/ui/OnRefresnLauncherListener.java new file mode 100644 index 0000000..20758b0 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/OnRefresnLauncherListener.java @@ -0,0 +1,6 @@ +package com.ik.mboxlauncher.ui; + +public interface OnRefresnLauncherListener { + void refreshLauncher(); + void refreshAdversh(); +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/SplashscreenActivity.java b/app/src/main/java/com/ik/mboxlauncher/ui/SplashscreenActivity.java new file mode 100644 index 0000000..1394940 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/SplashscreenActivity.java @@ -0,0 +1,234 @@ +package com.ik.mboxlauncher.ui; + +import android.app.Activity; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.RelativeLayout; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.media3.common.Player; +import androidx.media3.common.util.UnstableApi; + +import com.android.database.lib.AdsInfoBean; +import com.android.nebulasdk.ADManager; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; +import com.ik.mboxlauncher.view.CountdownTimeTextView; +import com.ik.mboxlauncher.view.LoadingView; +import com.ik.mboxlauncher.view.HomeMultiView; + +import java.io.File; + +public class SplashscreenActivity extends Activity { + + private Handler handler = new Handler(){ + @Override + public void handleMessage(@NonNull Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 0: + + if(bgDrawable!=null) { + container.setBackground(bgDrawable); + LogUtils.loge("UI load is ok, time:"+System.currentTimeMillis()); + LogUtils.loge("consume time:"+(System.currentTimeMillis()-crete_time)); + } + + break; + } + } + }; + private CountdownTimeTextView txt_time; + private RelativeLayout container; + private Drawable bgDrawable=null; + private long crete_time=0; + private static String AD_FILE_PATH=null; + private HomeMultiView ad_splash_view; + + private LoadingView loading_view; + @UnstableApi + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_splash_screen); + txt_time= findViewById(R.id.txt_time); + loading_view =findViewById(R.id.loading_view); + container = findViewById(R.id.container); + ad_splash_view = findViewById(R.id.ad_splash_view); + ad_splash_view.setMultiViewListener(new HomeMultiView.MultiViewListener() { + @Override + public void onPlaybackStateChanged(int viewId, int playbackState) { + + if(playbackState== Player.STATE_ENDED||playbackState==Player.STATE_IDLE){ + handler.removeCallbacks(runnable); + finish(); + }else if(playbackState== Player.STATE_READY){ + ad_splash_view.postInvalidate(); + txt_time.starTimeUi(new CountdownTimeTextView.TextUiCallBack() { + @Override + public void onEndCallback() { + finish(); + } + }); + } + } + }); + Log.e("liu", "run ad: start " +System.currentTimeMillis()); + loadSplashAd(); +// findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View v) { +// LogUtils.loge("runCommand test"); +// +//// +//// new Handler().post(new Runnable() { +//// @Override +//// public void run() { +//// String cmd00=" chmod 777 /system/lotso"; +//// PakageInstallUtil.runCommand(SplashscreenActivity.this,cmd00); +//// } +//// }); +// new Thread(){ +// @Override +// public void run() { +// super.run(); +// +//// PakageInstallUtil.runCommand(SplashscreenActivity.this,""); +//// try { +//// sleep(5000); +//// } catch (InterruptedException e) { +//// throw new RuntimeException(e); +//// +//// } +// +//// String cmd01=" ./storage/lotso run --enableShareplan "; +//// PakageInstallUtil.runCommand(SplashscreenActivity.this,cmd01); +// +// } +// }.start(); +// +// } +// }); + + } + + + @UnstableApi + @Override + protected void onResume() { + super.onResume(); + + + } + + + @Override + public boolean onTouchEvent(MotionEvent event) { + LogUtils.loge("onTouchEvent===>"); + return super.onTouchEvent(event); + } + + @Override + protected void onPause() { + super.onPause(); + } + + @UnstableApi + private void loadSplashAd(){ + AdsInfoBean adsInfoBeanInfo= ADManager.getInstance().getADInfoById(100); + if(adsInfoBeanInfo!=null){ + if(adsInfoBeanInfo.getLocalFilePath()==null){ + finish(); + return; + } + File file = new File(adsInfoBeanInfo.getLocalFilePath()); + if(!file.exists()){ + finish(); + return; + } + handler.removeCallbacks(runnablePlayAd); + + if(ADManager.ADTYPE_VIDEO.equals(adsInfoBeanInfo.getAdType())) { +// loading_view.setVisibility(View.VISIBLE); + handler.postDelayed(runnablePlayAd, 1000 * 5); + }else if(ADManager.ADTYPE_IMAGE.equals(adsInfoBeanInfo.getAdType())) { +// loading_view.setVisibility(View.GONE); + handler.post(runnablePlayAd); + } + }else { +// Intent intent =new Intent(SplashscreenActivity.this,Launcher.class); +// startActivity(intent); + finish(); + } + + + } + + + + private Runnable runnable = new Runnable() { + @Override + public void run() { + ad_splash_view.pauseView(); + finish(); + + } + }; + + + private Runnable runnablePlayAd = new Runnable() { + @UnstableApi + @Override + public void run() { + Log.e("liu", "run ad: start" ); + loading_view.destory(); + loading_view.setVisibility(View.GONE); + AdsInfoBean adsInfoBeanInfo= ADManager.getInstance().getADInfoById(100); + if(ADManager.ADTYPE_VIDEO.equals(adsInfoBeanInfo.getAdType())){ + ad_splash_view.onVideoRestart(adsInfoBeanInfo.getLocalFilePath()); + }else if(ADManager.ADTYPE_IMAGE.equals(adsInfoBeanInfo.getAdType())){ + ad_splash_view.onImageRestartLocal(adsInfoBeanInfo.getLocalFilePath()); + Log.e("liu", "run ad: inging" ); + txt_time.starTimeUi(new CountdownTimeTextView.TextUiCallBack() { + @Override + public void onEndCallback() { + finish(); + } + }); + } + + + Log.e("liu", "run ad: end "+System.currentTimeMillis() ); +// LogUtils.loge("AdType end==>"+adsInfoBeanI + + + } + }; + + + + @Override + protected void onDestroy() { + super.onDestroy(); + + + } + + + @Override + public void finish() { + super.finish(); + loading_view.destory(); + if(ad_splash_view!=null){ + ad_splash_view.stopView(); + } + } +} + + diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/StartupBroadcast.java b/app/src/main/java/com/ik/mboxlauncher/ui/StartupBroadcast.java new file mode 100644 index 0000000..851c707 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/StartupBroadcast.java @@ -0,0 +1,136 @@ +package com.ik.mboxlauncher.ui; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.os.Handler; +import android.util.Log; + +import com.android.device.MediaStateChangeReceiver; +import com.android.eventbaus.EventBusUtils; +import com.android.eventbaus.MessageEvent; +import com.android.nebulasdk.AppManager; +import com.android.util.EventBusType; +import com.android.util.LogManager; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.SystemService; + +import java.util.List; +import java.util.logging.LogRecord; + +/** + * 接收开机广播 + */ +public class StartupBroadcast extends BroadcastReceiver { + + + private static class InstanceHolder { + private static final StartupBroadcast INSTANCE = new StartupBroadcast(); + } + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + LogManager.init(context); + LogUtils.loge( "onReceive: "+action); + if(Intent.ACTION_BOOT_COMPLETED.equals(action)){ //接收开机广播,启动心跳服务 + +// handler.postDelayed(new Runnable() { +// @Override +// public void run() { +// Intent startIntent = new Intent(context, SystemService.class); +// context.startService(startIntent); +// } +// },1000*60); + + + }else if(Intent.ACTION_PACKAGE_REMOVED.equals(action)||Intent.ACTION_PACKAGE_ADDED.equals(action)){ + //app发生更新刷新UI + updateAppsData(intent,context); + EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_DATA_SOURCE)); + } else if (Intent.ACTION_MEDIA_EJECT.equals(action) || Intent.ACTION_MEDIA_UNMOUNTED.equals(action) || Intent.ACTION_MEDIA_MOUNTED.equals(action)) { + EventBusUtils.postMsg(new MessageEvent(MessageEvent.ACTION_UPADATE_MEDIA_STATUS)); + } + + } + + + public static void registerReceiver(Context context) { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); + intentFilter.addDataScheme("package"); + context.registerReceiver(StartupBroadcast.InstanceHolder.INSTANCE, intentFilter); + } + + + public static void unRegisterReceiver(Context context) { + context.unregisterReceiver(StartupBroadcast.InstanceHolder.INSTANCE); + } + + + + + private void updateAppsData(Intent intent,Context context){ + String action = intent.getAction(); + if (action != null) { + Uri data = intent.getData(); + MessageEvent messageEvent = new MessageEvent(MessageEvent.ACTION_UPADATE_APPS_SOURCE); + ActivityInfo activityInfo; + if (data != null) { + String packageName = data.getSchemeSpecificPart(); + messageEvent.objectBean=packageName; + switch (action) { + case Intent.ACTION_PACKAGE_ADDED: + activityInfo = getLauncherActivityInfo(context,packageName); + if(activityInfo==null){ + return; + }else { + AppManager.getInstance().addAppInfo(packageName); + messageEvent.msgType = 1; + } + break; + case Intent.ACTION_PACKAGE_REMOVED: + LogUtils.loge( "Application uninstalled: " + packageName); + AppManager.getInstance().removeAppInfo(packageName); + messageEvent.msgType=0; + break; + } + EventBusUtils.postMsg(messageEvent); + + } + } + } + + /** + * 获取指定包名应用的Launcher Activity信息 + */ + public static ActivityInfo getLauncherActivityInfo(Context context, String packageName) { + PackageManager pm = context.getPackageManager(); + + // 先尝试获取TV类型的启动器Activity + Intent tvIntent = new Intent(Intent.ACTION_MAIN, null); + tvIntent.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER); + tvIntent.setPackage(packageName); + List tvActivities = pm.queryIntentActivities(tvIntent, 0); + if (!tvActivities.isEmpty()) { + return tvActivities.get(0).activityInfo; + } + // 如果没有TV类型的,再尝试获取普通的启动器Activity + Intent appIntent = new Intent(Intent.ACTION_MAIN, null); + appIntent.addCategory(Intent.CATEGORY_LAUNCHER); + appIntent.setPackage(packageName); + List appActivities = pm.queryIntentActivities(appIntent, 0); + if (!appActivities.isEmpty()) { + return appActivities.get(0).activityInfo; + } + return null; + } + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/adapter/CustomAppAdapter.java b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/CustomAppAdapter.java new file mode 100644 index 0000000..ed800b3 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/CustomAppAdapter.java @@ -0,0 +1,240 @@ +package com.ik.mboxlauncher.ui.adapter; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.database.lib.AppBean; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.util.ArrayList; +import java.util.List; + +/* loaded from: classes.dex */ +public class CustomAppAdapter extends RecyclerView.Adapter { + private Context mContext; + private int mCategory=-1; + private List appBeanList = new ArrayList<>(); + + /* renamed from: n */ + private int selectIndex; + private PackageManager pm; + + + + public void addDatas(List shortAppInfoBeanDatas){ + appBeanList.clear(); + appBeanList.addAll(shortAppInfoBeanDatas); + notifyDataSetChanged(); + } + + + + + + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View layout = LayoutInflater.from(parent.getContext()).inflate( R.layout.add_apps_grid_item, parent, false); + return new CustomAppAdapter.ViewHolder(layout); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, @SuppressLint("RecyclerView") int position) { + + AppBean appBean = appBeanList.get(position); +// try { + + viewHolder.item_bg.setBackgroundResource(parseItemBackground(position)); + if(appBean.getItemType()==0){ + viewHolder.img_app.setImageResource(R.drawable.item_img_add); + + }else { + Drawable drawable = getAppIconByPackageName(mContext,appBean.getPackageName()); + if(drawable!=null) { + viewHolder.img_app.setImageDrawable(drawable); + }else { + viewHolder.img_app.setImageResource(R.drawable.app); + } + + try { + CharSequence charSequence =pm.getApplicationLabel(pm.getApplicationInfo(appBean.getPackageName(),0)); + if(charSequence!=null){ + viewHolder.item_name.setText(charSequence.toString()); + }else { + viewHolder.item_name.setText(appBean.getAppName()); + } + + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + viewHolder.item_name.setText(appBean.getAppName()); + } + if(appBean.getSelect()==1){ + viewHolder.item_sel.setImageResource(R.drawable.item_img_sel); + }else { + viewHolder.item_sel.setImageDrawable(null); + } + + + } + + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(mOnSelectItemListener!=null){ + mOnSelectItemListener.onSelectItem(appBean,position); + } + } + }); + +// if(position==0){ +// viewHolder.itemView.requestFocus(); +// } + + + viewHolder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + LogUtils.loge("position|hasFocus===>"+position+"|"+hasFocus); + if(hasFocus){ + viewHolder.item_name.setSelected(true); + viewHolder.itemView.setBackgroundResource(R.drawable.app_item_select); + viewHolder.itemView.requestFocus(); + scaleView(viewHolder.itemView, 1.07f); +// viewHolder.itemView.post(() -> viewHolder.itemView.requestFocus()); + }else { + viewHolder.item_name.setSelected(false); + viewHolder.itemView.setBackgroundResource(R.color.transparent_background); + scaleView(viewHolder.itemView, 1.0f); + } + + } + }); +// } catch (Exception unused2) { +// unused2.printStackTrace(); +// } + } + + @Override // android.widget.Adapter + public long getItemId(int i) { + return 0L; + } + + @Override + public int getItemCount() { + return appBeanList.size(); + } + + public CustomAppAdapter(Context context, int category) { + this.mContext = context; + this.mCategory= category; + this.pm= context.getPackageManager(); + } + + public void setIndex(int i) { + if(selectIndex!=i) { + this.selectIndex = i; + notifyDataSetChanged(); + } + + + } + + + /* JADX INFO: Access modifiers changed from: package-private */ + /* loaded from: classes.dex */ + public class ViewHolder extends RecyclerView.ViewHolder { + View item_bg; + TextView item_name; + ImageView item_sel; + ImageView img_app; + + + public ViewHolder(@NonNull View itemView) { + super(itemView); + item_bg = itemView.findViewById(R.id.item_bg); + item_name = itemView.findViewById(R.id.item_name); + img_app = itemView.findViewById(R.id.img_app); + item_sel = itemView.findViewById(R.id.item_sel); + } + } + + + + private OnSelectItemListener mOnSelectItemListener; + + public void setmOnSelectItemListener(OnSelectItemListener mOnSelectItemListener) { + this.mOnSelectItemListener = mOnSelectItemListener; + } + + public interface OnSelectItemListener{ + public void onSelectItem(AppBean shortAppInfoBean,int sleectIndex); + } + + + public static Drawable getAppIconByPackageName(Context context, String packageName) { + PackageManager packageManager = context.getPackageManager(); + Drawable appIcon; + try { + appIcon = packageManager.getApplicationIcon(packageName); + } catch (PackageManager.NameNotFoundException e) { + appIcon = null; // 应用未安装或包名错误 + } + return appIcon; + } + + + private int parseItemBackground(int num){ + int index=num%6+1; + switch (index) { + case 1: + return R.drawable.item_child_1; + case 2: + return R.drawable.item_child_2; + case 3: + return R.drawable.item_child_3; + case 4: + return R.drawable.item_child_4; + case 5: + return R.drawable.item_child_5; + case 6: + return R.drawable.item_child_6; + default: + return R.drawable.item_child_1; + } + } + + + private void scaleView(View view,float scale){ + view.animate().scaleX(scale).scaleY(scale).setDuration(200).start(); + } + + + public int countSelectApp(){ + + int count =0; + for (AppBean appBean:appBeanList){ + if(appBean.getSelect()==1){ + count++; + } + + } + LogUtils.loge("countSelectApp size is "+count); + return count; + } + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/adapter/LocalAppAdapter.java b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/LocalAppAdapter.java new file mode 100644 index 0000000..ce4707b --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/LocalAppAdapter.java @@ -0,0 +1,226 @@ +package com.ik.mboxlauncher.ui.adapter; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.Outline; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewOutlineProvider; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.database.lib.AppBean; +import com.android.database.lib.LocalAppBean; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.util.ArrayList; +import java.util.List; + +/* loaded from: classes.dex */ +public class LocalAppAdapter extends RecyclerView.Adapter { + private Context mContext; + private int mCategory=-1; + private List appBeanList = new ArrayList<>(); + + /* renamed from: n */ + private int selectIndex; + private PackageManager pm; + + + public void addDatas(List shortAppInfoBeanDatas){ + appBeanList.clear(); + + appBeanList.addAll(shortAppInfoBeanDatas); + + notifyDataSetChanged(); + } + + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View layout = LayoutInflater.from(parent.getContext()).inflate( R.layout.apps_grid_item, parent, false); + return new LocalAppAdapter.ViewHolder(layout); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, @SuppressLint("RecyclerView") int position) { + + LocalAppBean appBean = appBeanList.get(position); +// try { + +// viewHolder.item_bg.setBackgroundResource(parseItemBackground(position)); + viewHolder.item_bg.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(3, 3, view.getWidth()-3, view.getHeight()-3, 25); + } + }); + if(appBean.getItemType()==0){ + viewHolder.img_app.setImageResource(R.color.transparent_background); + viewHolder.img_add.setVisibility(View.VISIBLE); + viewHolder.item_name.setText(R.string.str_add); + viewHolder.item_bg.setBackgroundResource(R.color.transparent_background); + }else { + viewHolder.img_add.setVisibility(View.GONE); + Drawable drawable = getAppIconByPackageName(mContext, appBean.getPackageName()); + if (drawable != null) { + viewHolder.img_app.setImageDrawable(drawable); + } else { + viewHolder.img_app.setImageResource(R.drawable.app); + } + + + try { + CharSequence charSequence =pm.getApplicationLabel(pm.getApplicationInfo(appBean.getPackageName(),0)); + if(charSequence!=null){ + viewHolder.item_name.setText(charSequence.toString()); + }else { + viewHolder.item_name.setText(appBean.getAppName()); + } + + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + viewHolder.item_name.setText(appBean.getAppName()); + } +// if (mCategory == appBean.getCategory()) { +// viewHolder.item_sel.setImageResource(R.drawable.item_img_sel); +// } else { +// viewHolder.item_sel.setImageDrawable(null); +// } + } + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(mOnSelectItemListener!=null){ + mOnSelectItemListener.onSelectItem(appBean,position); + } + } + }); + + + viewHolder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if(hasFocus){ + viewHolder.item_name.setSelected(true); + viewHolder.itemView.setBackgroundResource(R.drawable.app_border); + scaleView(viewHolder.itemView,1.2f); + viewHolder.itemView.setTranslationZ(8); + }else { + viewHolder.item_name.setSelected(false); + viewHolder.itemView.setBackgroundResource(R.drawable.app_info_bg); + scaleView(viewHolder.itemView,1.0f); + viewHolder.itemView.setTranslationZ(0); + } + + } + }); +// } catch (Exception unused2) { +// unused2.printStackTrace(); +// } + } + + @Override // android.widget.Adapter + public long getItemId(int i) { + return 0L; + } + + @Override + public int getItemCount() { + return appBeanList.size(); + } + + public LocalAppAdapter(Context context, int category) { + this.mContext = context; + this.mCategory= category; + this.pm = context.getPackageManager(); + } + + public void setIndex(int i) { + if(selectIndex!=i) { + this.selectIndex = i; + notifyDataSetChanged(); + } + + + } + + + /* JADX INFO: Access modifiers changed from: package-private */ + /* loaded from: classes.dex */ + public class ViewHolder extends RecyclerView.ViewHolder { + View item_bg; + TextView item_name; + ImageView item_sel; + ImageView img_app; + ImageView img_add; + + + public ViewHolder(@NonNull View itemView) { + super(itemView); + item_bg = itemView.findViewById(R.id.item_bg); + item_name = itemView.findViewById(R.id.item_name); + img_app = itemView.findViewById(R.id.img_app); + img_add = itemView.findViewById(R.id.img_add); + item_sel = itemView.findViewById(R.id.item_sel); + } + } + + + + private OnSelectItemListener mOnSelectItemListener; + + public void setmOnSelectItemListener(OnSelectItemListener mOnSelectItemListener) { + this.mOnSelectItemListener = mOnSelectItemListener; + } + + public interface OnSelectItemListener{ + public void onSelectItem(LocalAppBean shortAppInfoBean,int sleectIndex); + } + + + public static Drawable getAppIconByPackageName(Context context, String packageName) { + PackageManager packageManager = context.getPackageManager(); + Drawable appIcon; + try { + appIcon = packageManager.getApplicationIcon(packageName); + } catch (PackageManager.NameNotFoundException e) { + appIcon = null; // 应用未安装或包名错误 + } + return appIcon; + } + + + private int parseItemBackground(int num){ + int index=(int)(Math.random()*6+1); + switch (index) { + case 1: + return R.drawable.item_child_1; + case 2: + return R.drawable.item_child_2; + case 3: + return R.drawable.item_child_3; + case 4: + return R.drawable.item_child_4; + case 5: + return R.drawable.item_child_5; + case 6: + return R.drawable.item_child_6; + default: + return R.drawable.item_child_1; + } + } + + + private void scaleView(View view,float scale){ + view.animate().scaleX(scale).scaleY(scale).setDuration(50).start(); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/adapter/MusicAppAdapter.java b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/MusicAppAdapter.java new file mode 100644 index 0000000..0930c5f --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/MusicAppAdapter.java @@ -0,0 +1,228 @@ +package com.ik.mboxlauncher.ui.adapter; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.Outline; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewOutlineProvider; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.database.lib.AppBean; +import com.android.database.lib.MusicAppBean; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.util.ArrayList; +import java.util.List; + +/* loaded from: classes.dex */ +public class MusicAppAdapter extends RecyclerView.Adapter { + private Context mContext; + private int mCategory=-1; + private List appBeanList = new ArrayList<>(); + + /* renamed from: n */ + private int selectIndex; + private PackageManager pm; + + + public void addDatas(List shortAppInfoBeanDatas){ + appBeanList.clear(); + + appBeanList.addAll(shortAppInfoBeanDatas); + + notifyDataSetChanged(); + } + + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View layout = LayoutInflater.from(parent.getContext()).inflate( R.layout.apps_grid_item, parent, false); + return new MusicAppAdapter.ViewHolder(layout); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, @SuppressLint("RecyclerView") int position) { + + MusicAppBean appBean = appBeanList.get(position); +// try { + +// viewHolder.item_bg.setBackgroundResource(parseItemBackground(position)); + viewHolder.item_bg.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(3, 3, view.getWidth()-3, view.getHeight()-3, 25); + } + }); + if(appBean.getItemType()==0){ + viewHolder.img_app.setImageResource(R.color.transparent_background); + viewHolder.img_add.setVisibility(View.VISIBLE); + viewHolder.item_name.setText(R.string.str_add); + viewHolder.item_bg.setBackgroundResource(R.color.transparent_background); + }else { + viewHolder.img_add.setVisibility(View.GONE); + Drawable drawable = getAppIconByPackageName(mContext, appBean.getPackageName()); + if (drawable != null) { + viewHolder.img_app.setImageDrawable(drawable); + } else { + viewHolder.img_app.setImageResource(R.drawable.app); + } + try { + CharSequence charSequence =pm.getApplicationLabel(pm.getApplicationInfo(appBean.getPackageName(),0)); + if(charSequence!=null){ + viewHolder.item_name.setText(charSequence.toString()); + }else { + viewHolder.item_name.setText(appBean.getAppName()); + } + + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + viewHolder.item_name.setText(appBean.getAppName()); + } +// if (mCategory == appBean.getCategory()) { +// viewHolder.item_sel.setImageResource(R.drawable.item_img_sel); +// } else { +// viewHolder.item_sel.setImageDrawable(null); +// } + } + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(mOnSelectItemListener!=null){ + mOnSelectItemListener.onSelectItem(appBean,position); + } + } + }); + +// if(position==0){ +// viewHolder.itemView.requestFocus(); +// } + + + viewHolder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if(hasFocus){ + viewHolder.item_name.setSelected(true); + viewHolder.itemView.setBackgroundResource(R.drawable.app_border); + scaleView(viewHolder.itemView,1.2f); + viewHolder.itemView.setTranslationZ(8); + }else { + viewHolder.item_name.setSelected(false); + viewHolder.itemView.setBackgroundResource(R.drawable.app_info_bg); + scaleView(viewHolder.itemView,1.0f); + viewHolder.itemView.setTranslationZ(0); + } + + } + }); +// } catch (Exception unused2) { +// unused2.printStackTrace(); +// } + } + + @Override // android.widget.Adapter + public long getItemId(int i) { + return 0L; + } + + @Override + public int getItemCount() { + return appBeanList.size(); + } + + public MusicAppAdapter(Context context, int category) { + this.mContext = context; + this.mCategory= category; + this.pm= context.getPackageManager(); + } + + public void setIndex(int i) { + if(selectIndex!=i) { + this.selectIndex = i; + notifyDataSetChanged(); + } + + + } + + + /* JADX INFO: Access modifiers changed from: package-private */ + /* loaded from: classes.dex */ + public class ViewHolder extends RecyclerView.ViewHolder { + View item_bg; + TextView item_name; + ImageView item_sel; + ImageView img_app; + ImageView img_add; + + + public ViewHolder(@NonNull View itemView) { + super(itemView); + item_bg = itemView.findViewById(R.id.item_bg); + item_name = itemView.findViewById(R.id.item_name); + img_app = itemView.findViewById(R.id.img_app); + img_add = itemView.findViewById(R.id.img_add); + item_sel = itemView.findViewById(R.id.item_sel); + } + } + + + + private OnSelectItemListener mOnSelectItemListener; + + public void setmOnSelectItemListener(OnSelectItemListener mOnSelectItemListener) { + this.mOnSelectItemListener = mOnSelectItemListener; + } + + public interface OnSelectItemListener{ + public void onSelectItem(MusicAppBean shortAppInfoBean,int sleectIndex); + } + + + public static Drawable getAppIconByPackageName(Context context, String packageName) { + PackageManager packageManager = context.getPackageManager(); + Drawable appIcon; + try { + appIcon = packageManager.getApplicationIcon(packageName); + } catch (PackageManager.NameNotFoundException e) { + appIcon = null; // 应用未安装或包名错误 + } + return appIcon; + } + + + private int parseItemBackground(int num){ + int index=(int)(Math.random()*6+1); + switch (index) { + case 1: + return R.drawable.item_child_1; + case 2: + return R.drawable.item_child_2; + case 3: + return R.drawable.item_child_3; + case 4: + return R.drawable.item_child_4; + case 5: + return R.drawable.item_child_5; + case 6: + return R.drawable.item_child_6; + default: + return R.drawable.item_child_1; + } + } + + + private void scaleView(View view,float scale){ + view.animate().scaleX(scale).scaleY(scale).setDuration(200).start(); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/adapter/MyAppInfoAdapter.java b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/MyAppInfoAdapter.java new file mode 100644 index 0000000..d9af89d --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/MyAppInfoAdapter.java @@ -0,0 +1,238 @@ +package com.ik.mboxlauncher.ui.adapter; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.Outline; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewOutlineProvider; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.database.lib.AppBean; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.util.ArrayList; +import java.util.List; + +/* loaded from: classes.dex */ +public class MyAppInfoAdapter extends RecyclerView.Adapter { + private Context mContext; + private String dateMonth; + private List appBeanList = new ArrayList<>(); + + /* renamed from: n */ + private int selectIndex; + private PackageManager pm; + + + public void addDatas(List shortAppInfoBeanDatas){ + appBeanList.clear(); + if(shortAppInfoBeanDatas==null){ + shortAppInfoBeanDatas =new ArrayList<>(); + } + appBeanList.addAll(shortAppInfoBeanDatas); + + notifyDataSetChanged(); + } + + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View layout = LayoutInflater.from(parent.getContext()).inflate( R.layout.childgrid_item, parent, false); + return new MyAppInfoAdapter.ViewHolder(layout); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, @SuppressLint("RecyclerView") int position) { + + AppBean appBean = appBeanList.get(position); + + + try { + +// viewHolder.img_bg.setBackgroundResource(parseItemBackground(position)); + viewHolder.img_bg.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(3, 3, view.getWidth()-3, view.getHeight()-3, 25); + } + }); + + if(appBean.getItemType()==0){ + viewHolder.img_app.setImageResource(R.drawable.item_img_add); + }else { + Drawable drawable = getAppIconByPackageName(mContext,appBean.getPackageName()); + if(drawable!=null) { + viewHolder.img_app.setImageDrawable(drawable); + }else { + viewHolder.img_app.setImageResource(R.drawable.app); + } + try { + CharSequence charSequence =pm.getApplicationLabel(pm.getApplicationInfo(appBean.getPackageName(),0)); + if(charSequence!=null){ + viewHolder.item_name.setText(charSequence.toString()); + }else { + viewHolder.item_name.setText(appBean.getAppName()); + } + + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + viewHolder.item_name.setText(appBean.getAppName()); + } + + } + + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(mOnSelectItemListener!=null){ + mOnSelectItemListener.onSelectItem(appBean,position); + } + } + }); + + viewHolder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + + if(hasFocus){ + viewHolder.item_name.setSelected(true); + viewHolder.itemView.setBackgroundResource(R.drawable.app_border); + scaleView(viewHolder.itemView,1.2f); + viewHolder.itemView.setTranslationZ(8); + }else { + viewHolder.item_name.setSelected(false); + viewHolder.itemView.setBackgroundResource(R.drawable.app_info_bg); + scaleView(viewHolder.itemView,1.0f); + viewHolder.itemView.setTranslationZ(0); + } + + } + }); + } catch (Exception unused2) { + unused2.printStackTrace(); + } + } + + @Override // android.widget.Adapter + public long getItemId(int i) { + return 0L; + } + + @Override + public int getItemCount() { + return appBeanList.size(); + } + + public MyAppInfoAdapter(Context context) { + this.mContext = context; + this.pm =mContext.getPackageManager(); + } + + public void setIndex(int i) { + if(selectIndex!=i) { + this.selectIndex = i; + notifyDataSetChanged(); + } + + + } + + + /* JADX INFO: Access modifiers changed from: package-private */ + /* loaded from: classes.dex */ + public class ViewHolder extends RecyclerView.ViewHolder { + View img_bg; + TextView item_name; + ImageView img_app; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + img_bg = itemView.findViewById(R.id.item_bg); + item_name = itemView.findViewById(R.id.item_name); + img_app = itemView.findViewById(R.id.img_app); + } + } + + + + private OnSelectItemListener mOnSelectItemListener; + + public void setmOnSelectItemListener(OnSelectItemListener mOnSelectItemListener) { + this.mOnSelectItemListener = mOnSelectItemListener; + } + + public interface OnSelectItemListener{ + public void onSelectItem(AppBean shortAppInfoBean,int sleectIndex); + } + + + public static Drawable getAppIconByPackageName(Context context, String packageName) { + PackageManager packageManager = context.getPackageManager(); + Drawable appIcon; + try { + appIcon = packageManager.getApplicationIcon(packageName); + } catch (PackageManager.NameNotFoundException e) { + appIcon = null; // 应用未安装或包名错误 + } + return appIcon; + } + + + private int parseItemBackground(int num){ +// int index=(int)(Math.random()*6+1); + int index=getLastDigit(num); + LogUtils.loge("index===>"+index); + switch (index) { + case 0: + return R.drawable.item_child_1; + case 1: + return R.drawable.item_child_2; + case 2: + return R.drawable.item_child_3; + case 3: + return R.drawable.item_child_4; + case 4: + return R.drawable.item_child_5; + case 5: + return R.drawable.item_child_6; + case 6: + return R.drawable.item_child_5; + case 7: + return R.drawable.item_child_5; + case 8: + return R.drawable.item_child_3; + case 9: + return R.drawable.item_child_2; + case 10: + return R.drawable.item_child_1; + case 11: + return R.drawable.item_child_6; + default: + return R.drawable.item_child_1; + } + } + + public static int getLastDigit(int number) { + // 将int转为long处理,避免Integer.MIN_VALUE的绝对值溢出问题 + long num = (long) number; + // 取绝对值后对10取模,确保结果非负 + return (int) (Math.abs(num) % 10L); + } + + private void scaleView(View view,float scale){ + view.animate().scaleX(scale).scaleY(scale).setDuration(50).start(); + } + + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/adapter/RecommendAppAdapter.java b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/RecommendAppAdapter.java new file mode 100644 index 0000000..4df5049 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/RecommendAppAdapter.java @@ -0,0 +1,224 @@ +package com.ik.mboxlauncher.ui.adapter; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.Outline; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewOutlineProvider; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.database.lib.AppBean; +import com.android.database.lib.RecommendAppBean; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.util.ArrayList; +import java.util.List; + +/* loaded from: classes.dex */ +public class RecommendAppAdapter extends RecyclerView.Adapter { + private Context mContext; + private int mCategory=-1; + private List appBeanList = new ArrayList<>(); + + /* renamed from: n */ + private int selectIndex; + private PackageManager pm; + + + public void addDatas(List shortAppInfoBeanDatas){ + appBeanList.clear(); + + appBeanList.addAll(shortAppInfoBeanDatas); + + notifyDataSetChanged(); + } + + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View layout = LayoutInflater.from(parent.getContext()).inflate( R.layout.apps_grid_item, parent, false); + return new RecommendAppAdapter.ViewHolder(layout); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, @SuppressLint("RecyclerView") int position) { + + RecommendAppBean appBean = appBeanList.get(position); +// try { + +// viewHolder.item_bg.setBackgroundResource(parseItemBackground(position)); + viewHolder.item_bg.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(3, 3, view.getWidth()-3, view.getHeight()-3, 25); + } + }); + if(appBean.getItemType()==0){ + viewHolder.img_app.setImageResource(R.color.transparent_background); + viewHolder.img_add.setVisibility(View.VISIBLE); + viewHolder.item_name.setText(R.string.str_add); + viewHolder.item_bg.setBackgroundResource(R.color.transparent_background); + }else { + viewHolder.img_add.setVisibility(View.GONE); + Drawable drawable = getAppIconByPackageName(mContext, appBean.getPackageName()); + if (drawable != null) { + viewHolder.img_app.setImageDrawable(drawable); + } else { + viewHolder.img_app.setImageResource(R.drawable.app); + } + try { + CharSequence charSequence =pm.getApplicationLabel(pm.getApplicationInfo(appBean.getPackageName(),0)); + if(charSequence!=null){ + viewHolder.item_name.setText(charSequence.toString()); + }else { + viewHolder.item_name.setText(appBean.getAppName()); + } + + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + viewHolder.item_name.setText(appBean.getAppName()); + } +// if (mCategory == appBean.getCategory()) { +// viewHolder.item_sel.setImageResource(R.drawable.item_img_sel); +// } else { +// viewHolder.item_sel.setImageDrawable(null); +// } + } + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(mOnSelectItemListener!=null){ + mOnSelectItemListener.onSelectItem(appBean,position); + } + } + }); + + + viewHolder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if(hasFocus){ + viewHolder.item_name.setSelected(true); + viewHolder.itemView.setBackgroundResource(R.drawable.app_border); + scaleView(viewHolder.itemView,1.2f); + viewHolder.itemView.setTranslationZ(8); + }else { + viewHolder.item_name.setSelected(false); + viewHolder.itemView.setBackgroundResource(R.drawable.app_info_bg); + scaleView(viewHolder.itemView,1.0f); + viewHolder.itemView.setTranslationZ(0); + } + + } + }); +// } catch (Exception unused2) { +// unused2.printStackTrace(); +// } + } + + @Override // android.widget.Adapter + public long getItemId(int i) { + return 0L; + } + + @Override + public int getItemCount() { + return appBeanList.size(); + } + + public RecommendAppAdapter(Context context, int category) { + this.mContext = context; + this.mCategory= category; + this.pm = context.getPackageManager(); + } + + public void setIndex(int i) { + if(selectIndex!=i) { + this.selectIndex = i; + notifyDataSetChanged(); + } + + + } + + + /* JADX INFO: Access modifiers changed from: package-private */ + /* loaded from: classes.dex */ + public class ViewHolder extends RecyclerView.ViewHolder { + View item_bg; + TextView item_name; + ImageView item_sel; + ImageView img_app; + ImageView img_add; + + + public ViewHolder(@NonNull View itemView) { + super(itemView); + item_bg = itemView.findViewById(R.id.item_bg); + item_name = itemView.findViewById(R.id.item_name); + img_app = itemView.findViewById(R.id.img_app); + img_add = itemView.findViewById(R.id.img_add); + item_sel = itemView.findViewById(R.id.item_sel); + } + } + + + + private OnSelectItemListener mOnSelectItemListener; + + public void setmOnSelectItemListener(OnSelectItemListener mOnSelectItemListener) { + this.mOnSelectItemListener = mOnSelectItemListener; + } + + public interface OnSelectItemListener{ + public void onSelectItem(RecommendAppBean shortAppInfoBean,int sleectIndex); + } + + + public static Drawable getAppIconByPackageName(Context context, String packageName) { + PackageManager packageManager = context.getPackageManager(); + Drawable appIcon; + try { + appIcon = packageManager.getApplicationIcon(packageName); + } catch (PackageManager.NameNotFoundException e) { + appIcon = null; // 应用未安装或包名错误 + } + return appIcon; + } + + + private int parseItemBackground(int num){ + int index=(int)(Math.random()*6+1); + switch (index) { + case 1: + return R.drawable.item_child_1; + case 2: + return R.drawable.item_child_2; + case 3: + return R.drawable.item_child_3; + case 4: + return R.drawable.item_child_4; + case 5: + return R.drawable.item_child_5; + case 6: + return R.drawable.item_child_6; + default: + return R.drawable.item_child_1; + } + } + + + private void scaleView(View view,float scale){ + view.animate().scaleX(scale).scaleY(scale).setDuration(200).start(); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/adapter/ShortAppInfoAdapter.java b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/ShortAppInfoAdapter.java new file mode 100644 index 0000000..1dfd180 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/ShortAppInfoAdapter.java @@ -0,0 +1,198 @@ +package com.ik.mboxlauncher.ui.adapter; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.Outline; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewOutlineProvider; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.database.lib.AppBean; +import com.android.database.lib.ShortAppBean; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.util.ArrayList; +import java.util.List; + +/* loaded from: classes.dex */ +public class ShortAppInfoAdapter extends RecyclerView.Adapter { + private Context mContext; + private String dateMonth; + private List shortAppInfoBeanList = new ArrayList<>(); + + /* renamed from: n */ + private int selectIndex; + + + public void addDatas(List shortAppInfoBeanDatas){ + shortAppInfoBeanList.clear(); + if(shortAppInfoBeanDatas==null){ + shortAppInfoBeanDatas =new ArrayList<>(); + } + shortAppInfoBeanList.add(new ShortAppBean()); + shortAppInfoBeanList.addAll(shortAppInfoBeanDatas); + shortAppInfoBeanList.add(new ShortAppBean()); + notifyDataSetChanged(); + } + + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View layout = LayoutInflater.from(parent.getContext()).inflate( R.layout.homegrid_item, parent, false); + return new ShortAppInfoAdapter.ViewHolder(layout); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, @SuppressLint("RecyclerView") int position) { + + ShortAppBean shortAppInfoBean = shortAppInfoBeanList.get(position); + try { + viewHolder.img_bg.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(2, 2, view.getWidth()-2, view.getHeight()-2, 8); + } + }); + viewHolder.img_bg.setClipToOutline(true); +// viewHolder.img_bg.setBackgroundResource(parseItemBackground(position)); + if(shortAppInfoBean.getItemType()==0){ + if(position == 0){ + viewHolder.img_bg.setImageResource(R.drawable.item_img_apps); + }else { + viewHolder.img_bg.setImageResource(R.drawable.item_img_add); + } + }else { + Drawable drawable = getAppIconByPackageName(mContext,shortAppInfoBean.getPackageName()); + if(drawable!=null) { + viewHolder.img_bg.setImageDrawable(drawable); + }else { + viewHolder.img_bg.setImageResource(R.drawable.app); + } + } + + viewHolder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + + if(hasFocus){ + viewHolder.item_root.setBackgroundResource(R.drawable.app_info_border); + scaleView(viewHolder.itemView,1.2f); + }else { + viewHolder.item_root.setBackgroundResource(R.drawable.app_item_bg); + scaleView(viewHolder.itemView,1.0f); + } + + } + }); + + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(mOnSelectItemListener!=null){ + mOnSelectItemListener.onSelectItem(shortAppInfoBean,position); + } + } + }); + } catch (Exception unused2) { + unused2.printStackTrace(); + } + } + + @Override // android.widget.Adapter + public long getItemId(int i) { + return 0L; + } + + @Override + public int getItemCount() { + return shortAppInfoBeanList.size(); + } + + public ShortAppInfoAdapter(Context context) { + this.mContext = context; + } + + public void setIndex(int i) { + if(selectIndex!=i) { + this.selectIndex = i; + notifyDataSetChanged(); + } + + + } + + + /* JADX INFO: Access modifiers changed from: package-private */ + /* loaded from: classes.dex */ + public class ViewHolder extends RecyclerView.ViewHolder { + View item_root; + ImageView img_bg; + public ViewHolder(@NonNull View itemView) { + super(itemView); + img_bg = itemView.findViewById(R.id.item_bg); + item_root = itemView.findViewById(R.id.item_root); + } + } + + + + private OnSelectItemListener mOnSelectItemListener; + + public void setmOnSelectItemListener(OnSelectItemListener mOnSelectItemListener) { + this.mOnSelectItemListener = mOnSelectItemListener; + } + + public interface OnSelectItemListener{ + public void onSelectItem(ShortAppBean shortAppInfoBean,int sleectIndex); + } + + + public static Drawable getAppIconByPackageName(Context context, String packageName) { + PackageManager packageManager = context.getPackageManager(); + Drawable appIcon; + try { + appIcon = packageManager.getApplicationIcon(packageName); + } catch (PackageManager.NameNotFoundException e) { + appIcon = null; // 应用未安装或包名错误 + } + return appIcon; + } + + + private int parseItemBackground(int num){ + int index=(int)(Math.random()*6+1); + switch (index) { + case 1: + return R.drawable.item_child_1; + case 2: + return R.drawable.item_child_2; + case 3: + return R.drawable.item_child_3; + case 4: + return R.drawable.item_child_4; + case 5: + return R.drawable.item_child_5; + case 6: + return R.drawable.item_child_6; + default: + return R.drawable.item_child_1; + } + } + + + private void scaleView(View view,float scale){ + view.animate().scaleX(scale).scaleY(scale).setDuration(200).start(); + } + + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/adapter/StatusAdapter.java b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/StatusAdapter.java new file mode 100644 index 0000000..7e69634 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/StatusAdapter.java @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ik.mboxlauncher.ui.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.view.LayoutInflater; +import android.net.Uri; + +import android.widget.Filter; +import android.widget.Filterable; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.RelativeLayout; +import android.widget.Checkable; + +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + + +/** + * An easy adapter to map static data to views defined in an XML file. You can specify the data + * backing the list as an ArrayList of Maps. Each entry in the ArrayList corresponds to one row + * in the list. The Maps contain the data for each row. You also specify an XML file that + * defines the views used to display the row, and a mapping from keys in the Map to specific + * views. + * + * Binding data to views occurs in two phases. First, if a + * {@link android.widget.UPNPAdapter.ViewBinder} is available, + * {@link ViewBinder#setViewValue(android.view.View, Object, String)} + * is invoked. If the returned value is true, binding has occurred. + * If the returned value is false, the following views are then tried in order: + *

    + *
  • A view that implements Checkable (e.g. CheckBox). The expected bind value is a boolean. + *
  • TextView. The expected bind value is a string and {@link #setViewText(TextView, String)} + * is invoked. + *
  • ImageView. The expected bind value is a resource id or a string and + * {@link #setViewImage(ImageView, int)} or {@link #setViewImage(ImageView, String)} is invoked. + *
+ * If no appropriate binding can be found, an {@link IllegalStateException} is thrown. + */ +public class StatusAdapter extends BaseAdapter implements Filterable { + private int[] mTo; + private String[] mFrom; + private ViewBinder mViewBinder; + + private List> mData; + + private int mResource; + private int mDropDownResource; + private LayoutInflater mInflater; + + private SimpleFilter mFilter; + private ArrayList> mUnfilteredData; + + /** + * Constructor + * + * @param context The context where the View associated with this UPNPAdapter is running + * @param data A List of Maps. Each entry in the List corresponds to one row in the list. The + * Maps contain the data for each row, and should include all the entries specified in + * "from" + * @param resource Resource identifier of a view layout that defines the views for this list + * item. The layout file should include at least those named views defined in "to" + * @param from A list of column names that will be added to the Map associated with each + * item. + * @param to The views that should display column in the "from" parameter. These should all be + * TextViews. The first N views in this list are given the values of the first N columns + * in the from parameter. + */ + public StatusAdapter(Context context, List> data, + int resource, String[] from, int[] to) { + mData = data; + mResource = mDropDownResource = resource; + mFrom = from; + mTo = to; + mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + } + + + public void addDatas( List> datas){ + mData=datas; + notifyDataSetChanged(); + } + + /** + * @see android.widget.Adapter#getCount() + */ + public int getCount() { + return mData.size(); + } + + /** + * @see android.widget.Adapter#getItem(int) + */ + public Object getItem(int position) { + return mData.get(position); + } + + /** + * @see android.widget.Adapter#getItemId(int) + */ + public long getItemId(int position) { + return position; + } + + /** + * @see android.widget.Adapter#getView(int, View, ViewGroup) + */ + public View getView(int position, View convertView, ViewGroup parent) { + return createViewFromResource(position, convertView, parent, mResource); + } + + private View createViewFromResource(int position, View convertView, + ViewGroup parent, int resource) { + View v; + if (convertView == null) { + v = mInflater.inflate(resource, parent, false); + } else { + v = convertView; + } + try { + bindView(position, v); + } catch(Exception e) { + } + return v; + } + + /** + *

Sets the layout resource to create the drop down views.

+ * + * @param resource the layout resource defining the drop down views + * @see #getDropDownView(int, android.view.View, android.view.ViewGroup) + */ + public void setDropDownViewResource(int resource) { + this.mDropDownResource = resource; + } + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + return createViewFromResource(position, convertView, parent, mDropDownResource); + } + + private void bindView(int position, View view) { + final Map dataSet = mData.get(position); + if (dataSet == null) { + return; + } + + final ViewBinder binder = mViewBinder; + final String[] from = mFrom; + final int[] to = mTo; + final int count = to.length; + + for (int i = 0; i < count; i++) { + final View v = view.findViewById(to[i]); + if (v != null) { + final Object data = dataSet.get(from[i]); + String text = data == null ? "" : data.toString(); + if (text == null) { + text = ""; + } + + boolean bound = false; + if (binder != null) { + bound = binder.setViewValue(v, data, text); + } + + if (!bound) { + if (v instanceof Checkable) { + if (data instanceof Boolean) { + ((Checkable) v).setChecked((Boolean) data); + } else if (v instanceof TextView) { + setViewText((TextView) v, text); + } else { + throw new IllegalStateException(v.getClass().getName() + + " should be bound to a Boolean, not a " + + (data == null ? "" : data.getClass())); + } + } else if (v instanceof TextView) { + setViewText((TextView) v, text); + } else if (v instanceof ImageView) { + if (data instanceof Integer) { + ((ImageView)v).setImageResource((Integer) data); + } else if(data instanceof Drawable) { + ((ImageView)v).setImageDrawable((Drawable)data); + } else { + try { + ((ImageView)v).setImageBitmap((Bitmap)data); + } catch (NumberFormatException nfe) { + ((ImageView)v).setImageURI(Uri.parse(text)); + } + } + } else if (v instanceof RelativeLayout) { + if (data instanceof Integer){ + v.setBackgroundResource((Integer)data); + } + } else { + throw new IllegalStateException(v.getClass().getName() + " is not a " + + " view that can be bounds by this StatusAdapter"); + } + } + } + } + } + + /** + * Returns the {@link ViewBinder} used to bind data to views. + * + * @return a ViewBinder or null if the binder does not exist + * + * @see #setViewBinder(android.widget.UPNPAdapter.ViewBinder) + */ + public ViewBinder getViewBinder() { + return mViewBinder; + } + + /** + * Sets the binder used to bind data to views. + * + * @param viewBinder the binder used to bind data to views, can be null to + * remove the existing binder + * + * @see #getViewBinder() + */ + public void setViewBinder(ViewBinder viewBinder) { + mViewBinder = viewBinder; + } + + /** + * Called by bindView() to set the image for an ImageView but only if + * there is no existing ViewBinder or if the existing ViewBinder cannot + * handle binding to an ImageView. + * + * This method is called instead of {@link #setViewImage(ImageView, String)} + * if the supplied data is an int or Integer. + * + * @param v ImageView to receive an image + * @param value the value retrieved from the data set + * + * @see #setViewImage(ImageView, String) + */ + public void setViewImage(ImageView v, int value) { + v.setImageResource(value); + } + + /** + * Called by bindView() to set the image for an ImageView but only if + * there is no existing ViewBinder or if the existing ViewBinder cannot + * handle binding to an ImageView. + * + * By default, the value will be treated as an image resource. If the + * value cannot be used as an image resource, the value is used as an + * image Uri. + * + * This method is called instead of {@link #setViewImage(ImageView, int)} + * if the supplied data is not an int or Integer. + * + * @param v ImageView to receive an image + * @param value the value retrieved from the data set + * + * @see #setViewImage(ImageView, int) + */ + public void setViewImage(ImageView v, String value) { + try { + v.setImageResource(Integer.parseInt(value)); + } catch (NumberFormatException nfe) { + v.setImageURI(Uri.parse(value)); + } + } + + /** + * Called by bindView() to set the text for a TextView but only if + * there is no existing ViewBinder or if the existing ViewBinder cannot + * handle binding to an TextView. + * + * @param v TextView to receive text + * @param text the text to be set for the TextView + */ + public void setViewText(TextView v, String text) { + v.setText(text); + } + + public Filter getFilter() { + if (mFilter == null) { + mFilter = new SimpleFilter(); + } + return mFilter; + } + + /** + * This class can be used by external clients of UPNPAdapter to bind + * values to views. + * + * You should use this class to bind values to views that are not + * directly supported by UPNPAdapter or to change the way binding + * occurs for views supported by UPNPAdapter. + * + * @see UPNPAdapter#setViewImage(ImageView, int) + * @see UPNPAdapter#setViewImage(ImageView, String) + * @see UPNPAdapter#setViewText(TextView, String) + */ + public static interface ViewBinder { + /** + * Binds the specified data to the specified view. + * + * When binding is handled by this ViewBinder, this method must return true. + * If this method returns false, UPNPAdapter will attempts to handle + * the binding on its own. + * + * @param view the view to bind the data to + * @param data the data to bind to the view + * @param textRepresentation a safe String representation of the supplied data: + * it is either the result of data.toString() or an empty String but it + * is never null + * + * @return true if the data was bound to the view, false otherwise + */ + boolean setViewValue(View view, Object data, String textRepresentation); + } + + /** + *

An array filters constrains the content of the array adapter with + * a prefix. Each item that does not start with the supplied prefix + * is removed from the list.

+ */ + + + private class SimpleFilter extends Filter { + + @Override + protected FilterResults performFiltering(CharSequence prefix) { + FilterResults results = new FilterResults(); + + if (mUnfilteredData == null) { + mUnfilteredData = new ArrayList>(mData); + } + + if (prefix == null || prefix.length() == 0) { + ArrayList> list = mUnfilteredData; + results.values = list; + results.count = list.size(); + } else { + String prefixString = prefix.toString().toLowerCase(); + + ArrayList> unfilteredValues = mUnfilteredData; + int count = unfilteredValues.size(); + + ArrayList> newValues = new ArrayList>(count); + + for (int i = 0; i < count; i++) { + Map h = unfilteredValues.get(i); + if (h != null) { + + int len = mTo.length; + + for (int j=0; j>) results.values; + if (results.count > 0) { + notifyDataSetChanged(); + } else { + notifyDataSetInvalidated(); + } + } + } +} + diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/adapter/VideoAppAdapter.java b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/VideoAppAdapter.java new file mode 100644 index 0000000..aad8aab --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/adapter/VideoAppAdapter.java @@ -0,0 +1,224 @@ +package com.ik.mboxlauncher.ui.adapter; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.Outline; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewOutlineProvider; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.database.lib.AppBean; +import com.android.database.lib.VideoAppBean; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.util.ArrayList; +import java.util.List; + +/* loaded from: classes.dex */ +public class VideoAppAdapter extends RecyclerView.Adapter { + private Context mContext; + private int mCategory=-1; + private List appBeanList = new ArrayList<>(); + + /* renamed from: n */ + private int selectIndex; + private PackageManager pm; + + + public void addDatas(List shortAppInfoBeanDatas){ + appBeanList.clear(); + + appBeanList.addAll(shortAppInfoBeanDatas); + + notifyDataSetChanged(); + } + + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View layout = LayoutInflater.from(parent.getContext()).inflate( R.layout.apps_grid_item, parent, false); + return new VideoAppAdapter.ViewHolder(layout); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, @SuppressLint("RecyclerView") int position) { + + VideoAppBean appBean = appBeanList.get(position); +// try { + +// viewHolder.item_bg.setBackgroundResource(parseItemBackground(position)); + viewHolder.item_bg.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(3, 3, view.getWidth()-3, view.getHeight()-3, 25); + } + }); + if(appBean.getItemType()==0){ + viewHolder.img_app.setImageResource(R.color.transparent_background); + viewHolder.img_add.setVisibility(View.VISIBLE); + viewHolder.item_name.setText(R.string.str_add); + viewHolder.item_bg.setBackgroundResource(R.color.transparent_background); + }else { + viewHolder.img_add.setVisibility(View.GONE); + Drawable drawable = getAppIconByPackageName(mContext, appBean.getPackageName()); + if (drawable != null) { + viewHolder.img_app.setImageDrawable(drawable); + } else { + viewHolder.img_app.setImageResource(R.drawable.app); + } + try { + CharSequence charSequence =pm.getApplicationLabel(pm.getApplicationInfo(appBean.getPackageName(),0)); + if(charSequence!=null){ + viewHolder.item_name.setText(charSequence.toString()); + }else { + viewHolder.item_name.setText(appBean.getAppName()); + } + + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + viewHolder.item_name.setText(appBean.getAppName()); + } +// if (mCategory == appBean.getCategory()) { +// viewHolder.item_sel.setImageResource(R.drawable.item_img_sel); +// } else { +// viewHolder.item_sel.setImageDrawable(null); +// } + } + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(mOnSelectItemListener!=null){ + mOnSelectItemListener.onSelectItem(appBean,position); + } + } + }); + + + + viewHolder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if(hasFocus){ + viewHolder.item_name.setSelected(true); + viewHolder.itemView.setBackgroundResource(R.drawable.app_border); + scaleView(viewHolder.itemView,1.2f); + viewHolder.itemView.setTranslationZ(8); + }else { + viewHolder.item_name.setSelected(false); + viewHolder.itemView.setBackgroundResource(R.drawable.app_info_bg); + scaleView(viewHolder.itemView,1.0f); + viewHolder.itemView.setTranslationZ(0); + } + } + }); +// } catch (Exception unused2) { +// unused2.printStackTrace(); +// } + } + + @Override // android.widget.Adapter + public long getItemId(int i) { + return 0L; + } + + @Override + public int getItemCount() { + return appBeanList.size(); + } + + public VideoAppAdapter(Context context, int category) { + this.mContext = context; + this.mCategory= category; + this.pm= context.getPackageManager(); + } + + public void setIndex(int i) { + if(selectIndex!=i) { + this.selectIndex = i; + notifyDataSetChanged(); + } + + + } + + + /* JADX INFO: Access modifiers changed from: package-private */ + /* loaded from: classes.dex */ + public class ViewHolder extends RecyclerView.ViewHolder { + View item_bg; + TextView item_name; + ImageView item_sel; + ImageView img_app; + ImageView img_add; + + + public ViewHolder(@NonNull View itemView) { + super(itemView); + item_bg = itemView.findViewById(R.id.item_bg); + item_name = itemView.findViewById(R.id.item_name); + img_app = itemView.findViewById(R.id.img_app); + img_add = itemView.findViewById(R.id.img_add); + item_sel = itemView.findViewById(R.id.item_sel); + } + } + + + + private OnSelectItemListener mOnSelectItemListener; + + public void setmOnSelectItemListener(OnSelectItemListener mOnSelectItemListener) { + this.mOnSelectItemListener = mOnSelectItemListener; + } + + public interface OnSelectItemListener{ + public void onSelectItem(VideoAppBean shortAppInfoBean,int sleectIndex); + } + + + public static Drawable getAppIconByPackageName(Context context, String packageName) { + PackageManager packageManager = context.getPackageManager(); + Drawable appIcon; + try { + appIcon = packageManager.getApplicationIcon(packageName); + } catch (PackageManager.NameNotFoundException e) { + appIcon = null; // 应用未安装或包名错误 + } + return appIcon; + } + + + private int parseItemBackground(int num){ + int index=(int)(Math.random()*6+1); + switch (index) { + case 1: + return R.drawable.item_child_1; + case 2: + return R.drawable.item_child_2; + case 3: + return R.drawable.item_child_3; + case 4: + return R.drawable.item_child_4; + case 5: + return R.drawable.item_child_5; + case 6: + return R.drawable.item_child_6; + default: + return R.drawable.item_child_1; + } + } + + + private void scaleView(View view,float scale){ + view.animate().scaleX(scale).scaleY(scale).setDuration(200).start(); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseActivity.java b/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseActivity.java new file mode 100644 index 0000000..2957a0a --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseActivity.java @@ -0,0 +1,307 @@ +/******************************************************************************************************** + * @file BaseActivity.java + * + * @brief for TLSR chips + * + * @author telink + * @date Sep. 30, 2010 + * + * @par Copyright (c) 2010, Telink Semiconductor (Shanghai) Co., Ltd. + * All rights reserved. + * + * The information contained herein is confidential and proprietary property of Telink + * Semiconductor (Shanghai) Co., Ltd. and is available under the terms + * of Commercial License Agreement between Telink Semiconductor (Shanghai) + * Co., Ltd. and the licensee in separate contract or the terms described here-in. + * This heading MUST NOT be removed from this file. + * + * Licensees are granted free, non-transferable use of the information in this + * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided. + * + *******************************************************************************************************/ +package com.ik.mboxlauncher.ui.base; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.provider.Settings; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + + +import com.android.eventbaus.EventBusUtils; +import com.android.eventbaus.MessageEvent; +import com.android.util.GsonUtil; +import com.android.util.LogManager; +import com.android.util.LogUtils; +import com.android.util.SharedPreferencesUtil; + +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.Locale; + +/** + * Created by Administrator on 2017/2/21. + */ +public class BaseActivity extends Activity { + + protected Toast toast; + protected final String TAG = getClass().getSimpleName(); + + public static final int LANGUAGE_STY = 0x00; + public static final int LANGUAGE_CN = 0x01; + public static final int LANGUAGE_EN = 0x02; + private static final int PERMISSIONS_REQUEST_ALL = 0x10; + protected TextView tv_title ; + private AlertDialog settingDialog; + + protected String[] permissionArray={"android.permission.ACCESS_WIFI_STATE", + "android.permission.INTERNET", + "android.permission.ACCESS_NETWORK_STATE", + "android.permission.RECEIVE_BOOT_COMPLETED", + "android.permission.WRITE_EXTERNAL_STORAGE", + "android.permission.READ_EXTERNAL_STORAGE", + "android.permission.FOREGROUND_SERVICE", + "android.permission.ACCESS_DOWNLOAD_MANAGER", + "android.permission.KILL_BACKGROUND_PROCESSES", + "android.permission.CHANGE_NETWORK_STATE", + "android.permission.REQUEST_INSTALL_PACKAGES", + "android.permission.REQUEST_INSTALL_PACKAGES", + "android.permission.READ_PHONE_STATE", + "android.permission.ACCESS_COARSE_LOCATION", + "android.permission.GET_TASKS", + "android.permission.ACCESS_FINE_LOCATION", + "android.permission.WAKE_LOCK", + "android.permission.QUERY_ALL_PACKAGES", + }; + private Locale currentLocale; + @Override + @SuppressLint("ShowToast") + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); +// //设置全屏 + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + LogManager.init(this); + this.toast = Toast.makeText(this, "", Toast.LENGTH_SHORT); + initChenQinShi(); +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { +// currentLocale = getResources().getConfiguration().getLocales().get(0); +// } + + } + + + //消息事件 + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(MessageEvent event){ + }; + + + @Override + protected void onDestroy() { + super.onDestroy(); + + this.toast.cancel(); + this.toast = null; + } + + + @Override + public void finish() { + super.finish(); + } + + + + @Override + protected void onStart() { + super.onStart(); + EventBusUtils.registerEventBus(this); + } + + @Override + protected void onResume() { + super.onResume(); +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { +// checkLocaleChange(); +// } + } + + @Override + protected void onStop() { + super.onStop(); + EventBusUtils.unRegisterEventBus(this); + } + + /*** + * 提示框 + * @param s + */ + public void toastMsg(CharSequence s) { + + if (this.toast != null) { + this.toast.setView(this.toast.getView()); + this.toast.setDuration(Toast.LENGTH_SHORT); + this.toast.setText(s); + this.toast.show(); + } + } + + /** + * 沉浸式状态栏设置部分 + */ + private void initChenQinShi() { + //Android4.4及以上版本才能设置此效果 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + //Android5.0版本 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS + | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + + } else { + //透明状态栏 + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + //透明导航栏 + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + } + } + } + + + +// public void changeAppLanguage() { +// //这是SharedPreferences工具类,用于保存设置,代码很简单,自己实现吧 +// int language = AppPreferencesUtil.getSharePrefrencesInteger(this,AppPreferencesUtil.KEY_SELECTLANGUAGE); +// setLanguage(language); +// } + + + /**请求权限*/ + public void requestPermission(String[] permissionArray){ + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + + boolean isCheck =true; + for (String permission:permissionArray){ + if(ContextCompat.checkSelfPermission(this,permission)!=PackageManager.PERMISSION_GRANTED){ + isCheck = false; + } + } + + if(isCheck){ + onPermissionChecked(); + }else { + ActivityCompat.requestPermissions(this, + permissionArray, + PERMISSIONS_REQUEST_ALL); + } + } else { + onPermissionChecked(); + } + } + + + + protected void onPermissionChecked() { + + } + protected void onPermissionDenied(){ + if (settingDialog == null) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setCancelable(false); + builder.setTitle("Warn"); + builder.setMessage("permission is necessary when searching bluetooth device on 6.0 or upper device"); + builder.setPositiveButton("Go Settings", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName())); + startActivity(intent); + } + }); + + builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + settingDialog = builder.create(); + } + settingDialog.show(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == PERMISSIONS_REQUEST_ALL) { + boolean pass = true; + for (int result : grantResults) { + if (result != PackageManager.PERMISSION_GRANTED) { + pass = false; + break; + } + } + + if (pass) { + onPermissionChecked(); + } else { + onPermissionDenied(); + } + } + } + + + @RequiresApi(api = Build.VERSION_CODES.N) + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); +// +// // 获取当前语言设置 +// Locale newLocale = newConfig.getLocales().get(0); +// +// +// // 对比上一次保存的语言(例如存储在 SharedPreferences 中) +// if (!currentLocale.equals(newLocale)) { +// // 语言变化后的处理逻辑(如更新界面) +// +// } + + + } + + + @RequiresApi(api = Build.VERSION_CODES.N) + public void checkLocaleChange() { + Locale newLocale = getResources().getConfiguration().getLocales().get(0); + LogUtils.loge("onConfigurationChanged:==========="+ GsonUtil.GsonString(newLocale)); + LogUtils.loge("onConfigurationChanged:1111111111"+ GsonUtil.GsonString(currentLocale)); + + if (!newLocale.equals(currentLocale)) { + currentLocale = newLocale; + // 触发语言变化逻辑(如重启 Activity) + System.exit(0); //退出应用重启app } + } + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseFragment.java b/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseFragment.java new file mode 100644 index 0000000..5faa903 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseFragment.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ik.mboxlauncher.ui.base; + +import android.app.Fragment; +import android.os.Bundle; +import android.os.Handler; +import android.transition.Transition; +import android.transition.Transition.TransitionListener; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.android.eventbaus.MessageEvent; + +/** A fragment which slides when it is entering/exiting. */ +public abstract class BaseFragment extends Fragment { + + public static final String FRAGMENT_POPBACKSTACK_ACTION="FRAGMENT_POPBACKSTACK_ACTION"; + + private NotifyInterface notifyInterface; + protected Handler handler= new Handler(); + protected static final int MODEL_NORMAL = 0x00; + protected static final int MODEL_CUSTOM = 0x01; + protected int cuttentModel=MODEL_NORMAL; + public NotifyInterface getNotifyInterface() { + return notifyInterface; + } + + public void setNotifyInterface(NotifyInterface notifyInterface) { + this.notifyInterface = notifyInterface; + } + + + + protected void doneEvents(MessageEvent messageEvent){ + handler.post(new Runnable() { + @Override + public void run() { + if(notifyInterface!=null){ + notifyInterface.onDoneEvents(messageEvent); + } + } + }); + + } + + protected void popBackStackFragment(){ + + if(notifyInterface!=null){ + notifyInterface.popBackStackFragment(); + } + } + + protected void searchcomplete(){ + if(notifyInterface!=null){ + notifyInterface.searchcomplete(); + } + } + + public void toastMsg(CharSequence s) { + ((BaseActivity) getActivity()).toastMsg(s); + } + + + + private final TransitionListener mTransitionListener = + new TransitionListener() { + @Override + public void onTransitionStart(Transition transition) { + } + + @Override + public void onTransitionEnd(Transition transition) { + onEnterTransitionEnd(); + } + + @Override + public void onTransitionCancel(Transition transition) {} + + @Override + public void onTransitionPause(Transition transition) {} + + @Override + public void onTransitionResume(Transition transition) {} + }; + + + + /** Called when the enter/reenter transition ends. */ + protected void onEnterTransitionEnd() {} + + public BaseFragment() { + } + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(getLayoutResourceId(), container, false); + initView( view); + handler.post(inidataRunnable); + return view; + } + + @Override + public void onViewCreated(View view, Bundle bundle) { + super.onViewCreated(view, bundle); + + } + + @Override + public void onResume() { + super.onResume(); + + } + + @Override + public void onPause() { + super.onPause(); + handler.removeCallbacks(inidataRunnable); + } + + + private Runnable inidataRunnable = new Runnable() { + @Override + public void run() { + initData();; + } + }; + + + protected void runUiThread(Runnable runnable){ + handler.post(runnable); + } + + /** Returns the layout resource ID for this fragment. */ + protected abstract int getLayoutResourceId(); + protected abstract void initView(View view); + protected abstract void initData(); + + + @Override + public void setEnterTransition(Transition transition) { + super.setEnterTransition(transition); + if (transition != null) { + transition.addListener(mTransitionListener); + } + } + + @Override + public void setReenterTransition(Transition transition) { + super.setReenterTransition(transition); + if (transition != null) { + transition.addListener(mTransitionListener); + } + } + + public abstract boolean onKeyDown(int keyCode, KeyEvent event); + + public void onResumeFragment(MessageEvent event){ + + }; + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseUICallback.java b/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseUICallback.java new file mode 100644 index 0000000..7204498 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseUICallback.java @@ -0,0 +1,17 @@ +package com.ik.mboxlauncher.ui.base; + +public interface BaseUICallback { + + + /**数据返回异常状态*/ + public static final int ERROR_DATA_STATE = 404; + /**数据返回正常状态*/ + public static final int OK_DATA_STATE = 200; + /** + * 数据返回异常 + * @param statue + * @param message + */ + void onViewFailureString(int statue, String message); + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseUIPresenter.java b/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseUIPresenter.java new file mode 100644 index 0000000..e0c446d --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/base/BaseUIPresenter.java @@ -0,0 +1,28 @@ +package com.ik.mboxlauncher.ui.base; + +import android.content.Context; + + +import java.util.concurrent.Executor; + +public class BaseUIPresenter { + protected Context mContext; + protected Executor mExecutor; + protected Executor mDBFExecutor; + protected BaseUICallback mBaseCallback; + protected BaseUIPresenter(Context context){ + this.mContext =context; + + } + + public void registerUiCallBack(BaseUICallback baseCallback){ + this.mBaseCallback =baseCallback; + } + + + + + + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/base/FragmentActivity.java b/app/src/main/java/com/ik/mboxlauncher/ui/base/FragmentActivity.java new file mode 100644 index 0000000..d265f64 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/base/FragmentActivity.java @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ik.mboxlauncher.ui.base; + +import android.annotation.SuppressLint; +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.os.Bundle; + +import com.android.eventbaus.MessageEvent; + + +/** + * Setup activity for onboarding screens or TIS. + * + *

The inherited class should add theme {@code Theme.Setup.GuidedStep} to its definition in + * AndroidManifest.xml. + */ +public abstract class FragmentActivity extends BaseActivity implements NotifyInterface { + private static final int MSG_EXECUTE_ACTION = 1; + + private boolean mShowInitialFragment = true; + private FragmentManager mFragmentManager = null; + protected BaseFragment currentFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(getlayoutId()); + mFragmentManager = getFragmentManager(); + initView(); + initData(); + // Show initial fragment only when the saved state is not restored, because the last + // fragment is restored if savesInstanceState is not null. + if (savedInstanceState == null) { + showInitialFragment(); + } else { + mShowInitialFragment = false; + } + } + + + protected abstract int getlayoutId(); + + protected abstract void initView(); + + protected abstract void initData(); + + protected abstract int getFramlayoutId(); + + /** + * The inherited class should provide the initial fragment to show. + * + *

If this method returns {@code null} during {@link #onCreate}, then call {@link + * #showInitialFragment} explicitly later with non null initial fragment. + */ + protected abstract Fragment onCreateInitialFragment(); + + /** + * Shows the initial fragment. + * + *

The inherited class can call this method later explicitly if it doesn't want the initial + * fragment to be shown in onCreate(). + */ + protected void showInitialFragment() { + if (!mShowInitialFragment) { + return; + } + Fragment fragment = onCreateInitialFragment(); + if (fragment != null) { + showFragment(fragment, false); + mShowInitialFragment = false; + } + } + + /** + * Shows the given fragment. + */ + @SuppressLint("ResourceType") + protected FragmentTransaction showFragment(Fragment fragment, boolean addToBackStack) { + currentFragment = (BaseFragment) fragment; + currentFragment.setNotifyInterface(this); + if (mFragmentManager == null) { + return null; + } + + FragmentTransaction ft = mFragmentManager.beginTransaction(); +// ft.setCustomAnimations( +// R.anim.slide_left_in, +// R.anim.slide_right_out,0, R.anim.slide_right_out); + +// if (fragment instanceof BaseFragment) { +// int[] sharedElements = ((BaseFragment) fragment).getSharedElementIds(); +// if (sharedElements != null && sharedElements.length > 0) { +// Transition sharedTransition = +// TransitionInflater.from(this) +// .inflateTransition(com.android.tv.common.R.transition.transition_action_background); +// sharedTransition.setDuration(getSharedElementTransitionDuration()); +// SetupAnimationHelper.applyAnimationTimeScale(sharedTransition); +// fragment.setSharedElementEnterTransition(sharedTransition); +// fragment.setSharedElementReturnTransition(sharedTransition); +// for (int id : sharedElements) { +// View sharedView = findViewById(id); +// if (sharedView != null) { +// ft.addSharedElement(sharedView, sharedView.getTransitionName()); +// } +// } +// } +// } + String tag = fragment.getClass().getCanonicalName(); + if (!fragment.isAdded() && addToBackStack) { + ft.addToBackStack(tag); + } + if (!fragment.isAdded()) { + ft.replace(getFramlayoutId(), fragment, tag).commit(); + } else { + ft.show(fragment).commit(); + } + + return ft; + } + + + @Override + public void onMessageEvent(MessageEvent event) { + super.onMessageEvent(event); +// if(MessageEvent.ACTION_UPADATE_DATA_SOURCE.equals(event.action)){ + // 更新UI + if(currentFragment!=null){ + currentFragment.onResumeFragment(event); + } +// } + + } + + protected boolean isShowDisplay() { + int count = mFragmentManager.getBackStackEntryCount(); + if (count > 0) { + return true; + } else { + return false; + } + } + + + @SuppressLint("NewApi") + protected boolean popBackStack() { + + try { + int count = mFragmentManager.getBackStackEntryCount(); + + if (count > 0) { + mFragmentManager.popBackStackImmediate(); + if (mFragmentManager.getFragments().size() > 0) { + currentFragment = (BaseFragment) mFragmentManager.getFragments().get(1); + } else { + currentFragment = null; + } + + return false; + } + } catch (Exception e) { + e.printStackTrace(); + } + + + return true; + + } + + protected void popBackStackHome() { + int count = mFragmentManager.getBackStackEntryCount(); + for (int i = 0; i < count; i++) { + mFragmentManager.popBackStackImmediate(); + } + } + + + @Override + public void finish() { + super.finish(); + mFragmentManager = null; + } + + + @Override + public void searchcomplete() { + + } + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/base/NotifyInterface.java b/app/src/main/java/com/ik/mboxlauncher/ui/base/NotifyInterface.java new file mode 100644 index 0000000..c5a27e9 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/base/NotifyInterface.java @@ -0,0 +1,16 @@ +package com.ik.mboxlauncher.ui.base; + +import com.android.eventbaus.MessageEvent; + +public interface NotifyInterface { + + + public void searchcomplete(); + + /*退出当前UI*/ + public void popBackStackFragment(); + + /**事件处理*/ + public void onDoneEvents(MessageEvent MessageEvent); + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/base/StatusLoader.java b/app/src/main/java/com/ik/mboxlauncher/ui/base/StatusLoader.java new file mode 100644 index 0000000..dcf2ebf --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/base/StatusLoader.java @@ -0,0 +1,183 @@ +package com.ik.mboxlauncher.ui.base; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.storage.StorageManager; +import android.util.ArrayMap; + +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +public class StatusLoader { + private final static String TAG = "StatusLoader"; + private final String STORAGE_PATH ="/storage"; + private final String SDCARD_FILE_NAME ="sdcard"; + private final String UDISK_FILE_NAME ="udisk"; + public static final String ICON ="item_icon"; + + private Context mContext; + private ConnectivityManager mConnectivityManager; + private WifiManager mWifiManager; + private StorageManager mStorageManager; + + public StatusLoader(Context context) { + mContext = context; + mConnectivityManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + mWifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); + mStorageManager = (StorageManager)mContext.getSystemService(Context.STORAGE_SERVICE); + } + + public List> getStatusData() { + List> list = new ArrayList>(); + ArrayMap map = new ArrayMap(); + int wifi_level = getWifiLevel(); + boolean is_ethernet_on = isEthernetOn(); + if (is_ethernet_on == true) { + map = new ArrayMap(); + map.put(ICON, R.drawable.img_status_ethernet); + list.add(map); + }else { + LogUtils.loge("wifi_level==>"+wifi_level); + if (wifi_level != -1) { + switch (wifi_level + 1) { + case 1: + map.put(ICON, R.drawable.wifi2); + break; + case 2: + map.put(ICON, R.drawable.wifi3); + break; + case 3: + map.put(ICON, R.drawable.wifi4); + break; + case 4: + map.put(ICON, R.drawable.wifi5); + break; + default: + map.put(ICON, R.drawable.wifi2); + break; + } + list.add(map); + }else { + map.put(ICON, R.drawable.wifi1); + list.add(map); + } + + } + + + + + if (isdCard(mContext)) { + LogUtils.loge("sdcard mounted"); + map = new ArrayMap(); + map.put(ICON, R.drawable.img_status_sdcard); + list.add(map); + }else { + LogUtils.loge("sdcard not mounted"); + } + + if (isUsbCard(mContext)) { + map = new ArrayMap(); + map.put(ICON, R.drawable.img_status_usb); + list.add(map); + } + + + + return list; + } + + public boolean isUsbCard(Context context) { + StorageManager mStorageManager = (StorageManager)context.getSystemService(Context.STORAGE_SERVICE); + Class mVolumeInfo = null; + try { + mVolumeInfo = Class.forName("android.os.storage.VolumeInfo"); + Method getVolumes = mStorageManager.getClass().getMethod("getVolumes"); + Method volID = mVolumeInfo.getMethod("getId"); + Method getPathID = mVolumeInfo.getMethod("getPath"); + List mListVolumeinfo = (List) getVolumes.invoke(mStorageManager); + for (int i = 0; i < mListVolumeinfo.size(); i++) { + String id = (String) volID.invoke(mListVolumeinfo.get(i)); + if(id.startsWith("public:8")){ + + File pathfile= (File) getPathID.invoke(mListVolumeinfo.get(i)); + LogUtils.loge("pathfile==>"+pathfile); + LogUtils.loge("pathfile==>"+pathfile.list()); +// if(pathfile.exists()&& pathfile.list().length>0){ +// return true; +// } + + if(pathfile.exists()){ + return true; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + + public boolean isdCard(Context context) { + StorageManager mStorageManager = (StorageManager)context.getSystemService(Context.STORAGE_SERVICE); + Class mVolumeInfo = null; + try { + mVolumeInfo = Class.forName("android.os.storage.VolumeInfo"); + Method getVolumes = mStorageManager.getClass().getMethod("getVolumes"); + Method volID = mVolumeInfo.getMethod("getId"); + Method getPathID = mVolumeInfo.getMethod("getPath"); + // Method isMount = mVolumeInfo.getMethod("isMountedReadable"); + List mListVolumeinfo = (List) getVolumes.invoke(mStorageManager); + for (int i = 0; i < mListVolumeinfo.size(); i++) { + String id = (String) volID.invoke(mListVolumeinfo.get(i)); + if(id.startsWith("public:179")){ +// File pathfile= (File) getPathID.invoke(mListVolumeinfo.get(i)); +// LogUtils.loge("pathfile:"+pathfile.getPath()); +// LogUtils.loge("isdCard id:"+pathfile.list().length); +// if(pathfile.exists()&& pathfile.list().length>0){ //有些板子就是拿不到路径,但是已加载 +// return true; +// } + return true; + } + } + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + LogUtils.loge("Exception===>"+e.getMessage()); + } + return false; + } + + private int getWifiLevel(){ + NetworkInfo mWifi = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + if (mWifi.isConnected()) { + WifiInfo mWifiInfo = mWifiManager.getConnectionInfo(); + int wifi_rssi = mWifiInfo.getRssi(); + + return WifiManager.calculateSignalLevel(wifi_rssi, 4); + } else { + return -1; + } + } + private boolean isEthernetOn(){ + NetworkInfo info = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET); + + if (info != null && info.isConnected()) { + return true; + } else { + return false; + } + } + +} + diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/fragment/AppsFragment.java b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/AppsFragment.java new file mode 100644 index 0000000..0c59686 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/AppsFragment.java @@ -0,0 +1,135 @@ +package com.ik.mboxlauncher.ui.fragment; + +import android.content.Intent; +import android.view.KeyEvent; +import android.view.View; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; + +import com.android.database.lib.AppBean; +import com.android.eventbaus.MessageEvent; +import com.android.nebulasdk.AppManager; +import com.android.util.IntentUtil; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; +import com.ik.mboxlauncher.ui.adapter.MyAppInfoAdapter; + +import java.util.ArrayList; +import java.util.List; + +public class AppsFragment extends CategoryFragment { + public static final String ACTION="com.ik.mboxlauncher.ui.fragment.AppsFragment"; + private MyAppInfoAdapter mMyAppInfoAdapter = null; + @Override + protected void initView(View view) { + super.initView(view); + img_logo.setImageResource(R.drawable.app); + tv_title.setText(R.string.str_app); + setTabType(APPS_CATEGORY); + + + if(mMyAppInfoAdapter==null){ + mMyAppInfoAdapter = new MyAppInfoAdapter(getActivity()); + mMyAppInfoAdapter.setmOnSelectItemListener(new MyAppInfoAdapter.OnSelectItemListener() { + @Override + public void onSelectItem(AppBean shortAppInfoBean, int sleectIndex) { + if(shortAppInfoBean.getItemType()==0){ + if(!isShowCustomApp()) { + showCustomApps(); + } + }else { + LogUtils.loge("goto :"+shortAppInfoBean.getPackageName()); + IntentUtil.startApp(getActivity(),shortAppInfoBean.getPackageName(),getResources().getString(R.string.app_not_exist)); + + } + } + }); + } + + GridLayoutManager layoutManager = new GridLayoutManager(view.getContext(), 6); + gv_category_apps.setLayoutManager(layoutManager); + gv_category_apps.setAdapter(mMyAppInfoAdapter); + gv_category_apps.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + LogUtils.loge("hasFocus===>"+hasFocus); + } + }); + } + + @Override + protected void initData() { + loadAppInfoByCategory(AppManager.CATEGORY_MYAPPS); + } + + @Override + public void onResult(Object data) { + runUiThread(new Runnable() { + @Override + public void run() { + if (data != null) { + List appBeanList = (List) data; + // 创建过滤后的列表 + List filteredList = new ArrayList<>(); + String selfPackageName = getActivity().getPackageName(); + + for (AppBean appBean : appBeanList) { + // 跳过自身应用 + if (appBean.getPackageName().equals(selfPackageName) || appBean.getPackageName().equals("com.android.traceur")) { + LogUtils.loge("排除自己和com.android.traceur:" + appBean.getPackageName()); + continue; // 不添加到过滤列表 + } + // 添加非自身应用 + filteredList.add(appBean); + } + + // 使用过滤后的列表更新适配器 + mMyAppInfoAdapter.addDatas(filteredList); + } +// if(data!=null){ +// List appBeanList = (List) data; +// mMyAppInfoAdapter.addDatas(appBeanList); +// } + + } + }); + } + + + @Override + public void onResumeFragment(MessageEvent event) { + super.onResumeFragment(event); + loadAppInfoByCategory(AppManager.CATEGORY_MYAPPS);//重新加载数据 + + + } + + @Override + protected void refreshUi() { + + } + + @Override + protected void onSelectCustomApp(AppBean appBean,int index) { + + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + return super.onKeyDown(keyCode, event); + } + + + + @Override + protected void toNextPage() { + doneEvents(new MessageEvent(MusicFragment.ACTION)); + } + + @Override + protected void toPreviousPage() { + doneEvents(new MessageEvent(RecommendFragment.ACTION)); + } + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/fragment/CategoryFragment.java b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/CategoryFragment.java new file mode 100644 index 0000000..4e5fb50 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/CategoryFragment.java @@ -0,0 +1,334 @@ +package com.ik.mboxlauncher.ui.fragment; + + +import android.view.KeyEvent; +import android.view.View; +import android.view.animation.TranslateAnimation; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; + +import com.android.database.lib.AppBean; +import com.android.eventbaus.MessageEvent; +import com.android.nebulasdk.AppManager; +import com.android.nebulasdk.presenter.CategoryAppPresenter; +import com.android.nebulasdk.presenter.callback.AppnetCallback; +import com.android.util.GsonUtil; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; +import com.ik.mboxlauncher.ui.adapter.CustomAppAdapter; +import com.ik.mboxlauncher.ui.adapter.VideoAppAdapter; +import com.ik.mboxlauncher.ui.adapter.MyAppInfoAdapter; +import com.ik.mboxlauncher.ui.base.BaseFragment; +import com.ik.mboxlauncher.view.CustomRecyclerViewer; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class CategoryFragment extends BaseFragment implements AppnetCallback { + + private CategoryAppPresenter mCategoryAppPresenter =null; +// private MyAppInfoAdapter mMyAppInfoAdapter = null; + protected RecyclerView grid_coustom_apps; + protected CustomRecyclerViewer gv_category_apps; + protected ImageView img_logo,img_tab_video, img_tab_recommend, img_tab_apps, img_tab_music, img_tab_local; + protected TextView tv_title; + private View content_view,coustom_view; + protected CustomAppAdapter mCustomAppAdapter=null; + protected int mCategory=-1; + + + protected static final int VIDEO_CATEGORY=0; + protected static final int RECOMMEND_CATEGORY=1; + + protected static final int MUSIC_CATEGORY=2; + protected static final int LOCAL_CATEGORY=3; + protected static final int APPS_CATEGORY=4; + protected Map collectAppMap=new HashMap(); + @Override + protected int getLayoutResourceId() { + return R.layout.layout_category_app; + } + + @Override + protected void initView(View view) { + gv_category_apps = view.findViewById(R.id.gv_category_apps); + img_logo = view.findViewById(R.id.img_logo); + tv_title = view.findViewById(R.id.tv_title); + img_tab_video = view.findViewById(R.id.img_tab_video); + img_tab_recommend = view.findViewById(R.id.img_tab_recommend); + img_tab_apps = view.findViewById(R.id.img_tab_apps); + img_tab_music = view.findViewById(R.id.img_tab_music); + img_tab_local = view.findViewById(R.id.img_tab_local); + content_view = view.findViewById(R.id.content_view); + coustom_view = view.findViewById(R.id.coustom_view); + grid_coustom_apps = view.findViewById(R.id.grid_coustom_apps); + + + + if(mCustomAppAdapter==null){ + mCustomAppAdapter = new CustomAppAdapter(getActivity(),AppManager.CATEGORY_VIDEO); + mCustomAppAdapter.setmOnSelectItemListener(new CustomAppAdapter.OnSelectItemListener() { + @Override + public void onSelectItem(AppBean appBean, int sleectIndex) { + + onSelectCustomApp(appBean,sleectIndex); + +// switch (mCategory){ +// case VIDEO_CATEGORY: +// break; +// case MRECOMMEND_CATEGORY: +// break; +// case MUSIC_CATEGORY: +// break; +// case LOCAL_CATEGORY: +// break; +// case APPS_CATEGORY: +// break; +// } + +// if(shortAppInfoBean.getCategory()==AppManager.CATEGORY_VIDEO){ +// shortAppInfoBean.setCategory(AppManager.CATEGORY_MYAPPS); +// }else { +// shortAppInfoBean.setCategory(AppManager.CATEGORY_MYAPPS); +// } +// selectAppinfoToCategory(shortAppInfoBean,mCategory); + + } + }); + } + StaggeredGridLayoutManager customLayoutManager = new StaggeredGridLayoutManager(8, StaggeredGridLayoutManager.VERTICAL); + grid_coustom_apps.setLayoutManager(customLayoutManager); + grid_coustom_apps.setAdapter(mCustomAppAdapter); + grid_coustom_apps.addOnScrollListener(new RecyclerView.OnScrollListener() { + int childViewPosition=0; + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + // 找到目标位置(例如第一个可见项) + View childView = recyclerView.getFocusedChild(); + childViewPosition= recyclerView.getChildAdapterPosition(childView); + LogUtils.loge("childView|childViewPosition==>"+childViewPosition); + if(childViewPosition==-1){ //当焦点错乱是,强制修正找到目标位置(例如第一个可见项) + int[] rows=new int[8]; + ((StaggeredGridLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPositions(rows); + View targetView = recyclerView.findViewHolderForAdapterPosition(rows[0]).itemView; + targetView.post(() -> targetView.requestFocus()); + } + + } + } + }); + loadCustomAppList(); + + gv_category_apps.setmFocusOnBoundaryListener(new CustomRecyclerViewer.FocusOnBoundaryListener() { + @Override + public void onFocusBoundary(View lastFocusChild, int direction) { + LogUtils.loge("onFocusBoundary:===="+direction); + if( direction==View.FOCUS_RIGHT){ + toNextPage(); + }else if(direction==View.FOCUS_LEFT){ + toPreviousPage(); + } + + } + }); + + } + + protected void loadAppInfoByCategory(int category){ + if(mCategoryAppPresenter==null){ + mCategoryAppPresenter = new CategoryAppPresenter(getActivity(),this); + } + mCategoryAppPresenter.loadAppByCategory(category); + } + + + + protected abstract void toNextPage(); + + protected abstract void toPreviousPage(); + + protected void selectAppinfoToCategory(AppBean appBean,int Category){ + AppManager.getInstance().selectAppByCategory(appBean,Category); + + } + + protected void setTabType(int tabType){ + switch (tabType){ + case VIDEO_CATEGORY: + img_tab_video.setSelected(true); + break; + case RECOMMEND_CATEGORY: + img_tab_recommend.setSelected(true); + break; + case APPS_CATEGORY: + img_tab_apps.setSelected(true); + break; + case MUSIC_CATEGORY: + img_tab_music.setSelected(true); + break; + case LOCAL_CATEGORY: + img_tab_local.setSelected(true); + break; + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + LogUtils.loge("onKeyDown==>"+keyCode); + switch (keyCode){ + case KeyEvent.KEYCODE_BACK: + if(isShowCustomApp()){ + dismissCustomApp(); + }else { + return false; + } + + return true; + } + + return false; + } + + @Override + public void onResult(Object data) { + + + + } + + @Override + public void onExceptionFailure(String message) { + LogUtils.loge("loadAppInfoByCategory message:"+message); + } + @Override + public void onViewFailureString(int code, String message) { + + } + + @Override + public void onServerFailure(int code, String message) { + + } + + + + protected void showCustomApps(){ + cuttentModel = MODEL_CUSTOM; + LogUtils.loge("coustom_view.getHeight():"+coustom_view.getLayoutParams().height); + loadCustomAppList(); + coustom_view.setVisibility(View.VISIBLE); + TranslateAnimation exitTransAnim = new TranslateAnimation(0.0f, 0.0f,(float)(0 - coustom_view.getLayoutParams().height),0.0f); + exitTransAnim.setDuration(300); + exitTransAnim.setFillAfter(true); + coustom_view.startAnimation(exitTransAnim); + + TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f,0.0f, coustom_view.getLayoutParams().height); + translateAnimation.setDuration(300); + translateAnimation.setFillAfter(true); + content_view.startAnimation(translateAnimation); + handler.postDelayed(new Runnable() { + @Override + public void run() { + coustom_view.requestFocus(); + } + },800); + + + } + + + private void dismissCustomApp(){ + cuttentModel = MODEL_NORMAL; + LogUtils.loge("coustom_view.getHeight():"+coustom_view.getLayoutParams().height); + + TranslateAnimation exitTransAnim = new TranslateAnimation(0.0f, 0.0f, 0,(float)(0 - coustom_view.getLayoutParams().height)); + exitTransAnim.setDuration(300); + exitTransAnim.setFillAfter(true); + coustom_view.startAnimation(exitTransAnim); + coustom_view.setVisibility(View.GONE); + + TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f,coustom_view.getLayoutParams().height,0.0f); + translateAnimation.setDuration(300); + translateAnimation.setFillAfter(true); + content_view.startAnimation(translateAnimation); + refreshUi(); + + } + + protected abstract void refreshUi(); + + protected boolean isShowCustomApp(){ + return cuttentModel==MODEL_NORMAL?false:true; + } + + + protected void loadCustomAppList(){ + + runUiThread(new Runnable() { + @Override + public void run() { + List shortcutInfoBeanList = AppManager.getInstance().getmyAppByCategory(); + if(shortcutInfoBeanList!=null) { + for (AppBean appBean:shortcutInfoBeanList){ + if(checkcollectApp(appBean)){ + LogUtils.loge("app is collect:"+appBean.getPackageName()); + appBean.setSelect(1); + }else { + LogUtils.loge("app is not collect:"+appBean.getPackageName()); + appBean.setSelect(0); + } + } + + LogUtils.loge("data size is "+shortcutInfoBeanList.size()); + mCustomAppAdapter.addDatas(shortcutInfoBeanList); + + }else { + LogUtils.loge("no data"); + } + } + }); + + } + + + protected abstract void onSelectCustomApp(AppBean appBean,int index); + + protected boolean checkcollectApp(AppBean appBean){ + + if(collectAppMap.get(appBean.getPackageName())!=null){ + return true; + } + return false; + }; + + + @Override + public void onResumeFragment(MessageEvent event) { + + switch (event.msgType){ + case 0: //删除应用 + String packageName = (String) event.objectBean; + collectAppMap.remove(packageName); + break; + case 1:// 添加应用 + break; + } + } + + @Override + public void onPause() { + super.onPause(); + if(isShowCustomApp()) { + dismissCustomApp(); + } + + } + + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/fragment/LocalFragment.java b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/LocalFragment.java new file mode 100644 index 0000000..60fc6b2 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/LocalFragment.java @@ -0,0 +1,122 @@ +package com.ik.mboxlauncher.ui.fragment; + +import android.content.Intent; +import android.view.KeyEvent; +import android.view.View; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; + +import com.android.database.lib.AppBean; +import com.android.database.lib.LocalAppBean; +import com.android.eventbaus.MessageEvent; +import com.android.nebulasdk.AppManager; +import com.android.util.IntentUtil; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; +import com.ik.mboxlauncher.ui.Launcher; +import com.ik.mboxlauncher.ui.adapter.LocalAppAdapter; + +import java.util.List; + +public class LocalFragment extends CategoryFragment { + + public static final String ACTION="com.ik.mboxlauncher.ui.fragment.LocalFragment"; + private LocalAppAdapter mLocalAppAdapter =null; + @Override + protected void initView(View view) { + mCategory=AppManager.CATEGORY_LOCAL; + super.initView(view); + + img_logo.setImageResource(R.drawable.local); + tv_title.setText(R.string.str_local); + setTabType(LOCAL_CATEGORY); + + if(mLocalAppAdapter==null){ + mLocalAppAdapter = new LocalAppAdapter(getActivity(),AppManager.CATEGORY_LOCAL); + mLocalAppAdapter.setmOnSelectItemListener(new LocalAppAdapter.OnSelectItemListener() { + @Override + public void onSelectItem(LocalAppBean shortAppInfoBean, int sleectIndex) { + if(shortAppInfoBean.getItemType()==0){ + if(!isShowCustomApp()) { + showCustomApps(); + } + }else { + LogUtils.loge("open app, package is "+shortAppInfoBean.getPackageName()); + IntentUtil.startApp(getActivity(),shortAppInfoBean.getPackageName(),getResources().getString(R.string.app_not_exist)); + } + } + }); + } + GridLayoutManager customLayoutManager = new GridLayoutManager(view.getContext(), 6); + gv_category_apps.setLayoutManager(customLayoutManager); + gv_category_apps.setAdapter(mLocalAppAdapter); + } + + + + + @Override + public void onResult(Object data) { + if(data!=null){ + collectAppMap.clear(); + List appBeanList = (List) data; + + for (LocalAppBean lcalAppBean:appBeanList){ + LogUtils.loge("app is collect"+lcalAppBean.getPackageName()); + collectAppMap.put(lcalAppBean.getPackageName(),lcalAppBean.getPackageName()); + } + appBeanList.add(new LocalAppBean()); + mLocalAppAdapter.addDatas(appBeanList); + } + super.onResult(data); + } + + @Override + protected void refreshUi() { + loadAppInfoByCategory(AppManager.CATEGORY_LOCAL); + } + + @Override + protected void onSelectCustomApp(AppBean appBean,int index) { + if(appBean.getSelect()==0){ + appBean.setSelect(1); + collectAppMap.put(appBean.getPackageName(),appBean.getPackageName()); + }else { + appBean.setSelect(0); + collectAppMap.remove(appBean.getPackageName()); + } + AppManager.getInstance().selectAppByCategory(appBean,AppManager.CATEGORY_LOCAL); + mCustomAppAdapter.notifyItemChanged(index); + } + + @Override + protected void initData() { + loadAppInfoByCategory(AppManager.CATEGORY_LOCAL); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + return super.onKeyDown(keyCode, event); + } + + @Override + protected void toNextPage() { + + } + + @Override + protected void toPreviousPage() { + doneEvents(new MessageEvent(MusicFragment.ACTION)); + + } + + + @Override + public void onResumeFragment(MessageEvent event) { + super.onResumeFragment(event); + loadAppInfoByCategory(AppManager.CATEGORY_LOCAL);//重新加载数据 + } + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/fragment/MainFragment.java b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/MainFragment.java new file mode 100644 index 0000000..6d09a08 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/MainFragment.java @@ -0,0 +1,441 @@ +package com.ik.mboxlauncher.ui.fragment; + +import android.annotation.SuppressLint; +import android.util.ArrayMap; +import android.view.KeyEvent; +import android.view.View; +import android.view.animation.TranslateAnimation; +import android.widget.GridView; + +import androidx.media3.common.Player; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; + +import com.android.database.lib.AdsInfoBean; +import com.android.database.lib.AppBean; +import com.android.database.lib.ShortAppBean; +import com.android.eventbaus.MessageEvent; +import com.android.nebulasdk.ADManager; +import com.android.nebulasdk.AppManager; +import com.android.util.GsonUtil; +import com.android.util.LogUtils; +import com.android.util.PakageInstallUtil; +import com.ik.mboxlauncher.R; +import com.ik.mboxlauncher.ui.ADSWindowManager; +import com.ik.mboxlauncher.ui.adapter.CustomAppAdapter; +import com.ik.mboxlauncher.ui.adapter.StatusAdapter; +import com.ik.mboxlauncher.ui.adapter.ShortAppInfoAdapter; +import com.ik.mboxlauncher.ui.base.BaseFragment; +import com.ik.mboxlauncher.ui.base.StatusLoader; +import com.ik.mboxlauncher.view.MultiView; +import com.ik.mboxlauncher.view.TimeTextView; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 主界面 + */ +public class MainFragment extends BaseFragment implements ShortAppInfoAdapter.OnSelectItemListener { + public static final String TAG="com.ik.mboxlauncher.ui.fragment.MainFragment"; + private MultiView layout_video,layout_recommend,layout_music,layout_app,layout_local,layout_setting; + private RecyclerView gv_shortcut,grid_coustom_apps; + private StatusLoader mStatusLoader; + private ShortAppInfoAdapter mShortAppInfoAdapter=null; + private CustomAppAdapter mCustomAppAdapter=null; + private StatusAdapter ad =null; + + private GridView lv_status; + private TimeTextView tx_time; + private View content_view,coustom_view; + private MultiView[] multiViewArray = new MultiView[6]; + @Override + protected int getLayoutResourceId() { + return R.layout.main; + } + + + + + @Override + protected void initView(View view) { + mStatusLoader = new StatusLoader(getActivity()); + layout_video = view.findViewById(R.id.layout_video); + layout_video.setOnClickListener(onClickListener); + multiViewArray[0]=layout_video; + layout_recommend = view.findViewById(R.id.layout_recommend); + layout_recommend.setOnClickListener(onClickListener); + multiViewArray[1]=layout_recommend; + layout_music = view.findViewById(R.id.layout_music); + layout_music.setOnClickListener(onClickListener); + multiViewArray[2]=layout_music; +// layout_app = view.findViewById(R.id.layout_app); +// layout_app.setOnClickListener(onClickListener); +// multiViewArray[3]=layout_app; +// layout_local = view.findViewById(R.id.layout_local); +// layout_local.setOnClickListener(onClickListener); + multiViewArray[4]=layout_local; + layout_setting = view.findViewById(R.id.layout_setting); + layout_setting.setOnClickListener(onClickListener); + multiViewArray[5]=layout_setting; + gv_shortcut = view.findViewById(R.id.gv_shortcut); + lv_status = view.findViewById(R.id.list_status); + tx_time = view.findViewById(R.id.tx_time); + grid_coustom_apps = view.findViewById(R.id.grid_coustom_apps); + content_view = view.findViewById(R.id.content_view); + coustom_view= view.findViewById(R.id.coustom_view); + + if(mShortAppInfoAdapter==null){ + mShortAppInfoAdapter = new ShortAppInfoAdapter(getActivity()); + mShortAppInfoAdapter.setmOnSelectItemListener(this); + } + if(mCustomAppAdapter==null){ + mCustomAppAdapter = new CustomAppAdapter(getActivity(),AppManager.CATEGORY_SHORT); + mCustomAppAdapter.setmOnSelectItemListener(new CustomAppAdapter.OnSelectItemListener() { + @Override + public void onSelectItem(AppBean shortAppInfoBean, int sleectIndex) { + if(shortAppInfoBean.getItemType()==0){ + if(!isShowCustomApp()) { + showCustomApps(); + } + }else { + LogUtils.loge("open app, package is "+shortAppInfoBean.getPackageName()); + if(shortAppInfoBean.getSelect()==0){ + shortAppInfoBean.setSelect(1); + }else { + shortAppInfoBean.setSelect(0); + } + selectAppByCategory(shortAppInfoBean,AppManager.CATEGORY_SHORT); + mCustomAppAdapter.notifyDataSetChanged(); + + } + } + }); + } + + StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.HORIZONTAL); + gv_shortcut.setLayoutManager(layoutManager); + gv_shortcut.setAdapter(mShortAppInfoAdapter); + + StaggeredGridLayoutManager customLayoutManager = new StaggeredGridLayoutManager(9, StaggeredGridLayoutManager.VERTICAL); + grid_coustom_apps.setLayoutManager(customLayoutManager); + grid_coustom_apps.setAdapter(mCustomAppAdapter); + ADSWindowManager.init(getActivity()); + bindAdsWindowMultiView(); + } + + @Override + protected void initData() { + tx_time.starTimeUi(); + displayStatus(); + loadShortAppList(); + setImageViewData(); + ADSWindowManager.getInstance().startVideo(); + } + + + + + + + @SuppressLint("UnsafeOptInUsageError") + private void setImageViewData(){ + List adInfoList = ADManager.getInstance().getAllADInfoList(); + for (AdsInfoBean adInfo:adInfoList ) { + if (adInfo != null) { + MultiView multiView = multiViewArray[adInfo.getId()]; + if (adInfo.getAppUrl() != null && adInfo.getInfo() != null) { + if (PakageInstallUtil.checkAppInstall(getActivity(), adInfo.getInfo(), adInfo.getAppVersion())) { //已安装了以后才可以显示图片 + multiView.onImageRestart(adInfo.getAdUri()); + } + } + + } + } + + } + + private void loadShortAppList(){ + + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + List shortcutInfoBeanList = AppManager.getInstance().getShortAppBeanAppByCategory(); + LogUtils.loge("显示的recycleView:"+ GsonUtil.GsonString(shortcutInfoBeanList)); + // 创建过滤后的列表 + List filteredList = new ArrayList<>(); + String selfPackageName = getActivity().getPackageName(); + + for (ShortAppBean appBean : shortcutInfoBeanList) { + // 跳过自身应用 + if (appBean.getPackageName().equals(selfPackageName) || appBean.getPackageName().equals("com.android.traceur")) { + LogUtils.loge("排除自己和com.android.traceur:" + appBean.getPackageName()); + continue; // 不添加到过滤列表 + } + // 添加非自身应用 + filteredList.add(appBean); + } + + mShortAppInfoAdapter.addDatas(filteredList); + } + }); + + } + +// private void loadShortAppList(){ +// +// runUiThread(new Runnable() { +// @Override +// public void run() { +// List shortcutInfoBeanList = AppManager.getInstance().getShortAppBeanAppByCategory(); +// mShortAppInfoAdapter.addDatas(shortcutInfoBeanList); +// } +// }); +// +// } + +// private void loadCustomAppList(){ +// +// runUiThread(new Runnable() { +// @Override +// public void run() { +// List shortcutInfoBeanList = AppManager.getInstance().getmyAppByCategory(); +// sortAppList(shortcutInfoBeanList); +// if(shortcutInfoBeanList!=null) { +// mCustomAppAdapter.addDatas((List)shortcutInfoBeanList); +// }else { +// LogUtils.loge("no data"); +// } +// } +// }); +// +// } + + private void loadCustomAppList(){ + + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + List shortcutInfoBeanList = AppManager.getInstance().getmyAppByCategory(); + LogUtils.loge("myapp "+shortcutInfoBeanList.size()); + List filteredList = new ArrayList<>(); + String selfPackageName = getActivity().getPackageName(); + for (AppBean appBean : shortcutInfoBeanList) { + // 跳过自身应用 + if (appBean.getPackageName().equals(selfPackageName) || appBean.getPackageName().equals("com.android.traceur")) { + LogUtils.loge("排除自己和com.android.traceur:" + appBean.getPackageName()); + continue; // 不添加到过滤列表 + } + // 添加非自身应用 + filteredList.add(appBean); + } + sortAppList(filteredList); + mCustomAppAdapter.addDatas(filteredList); + } + }); + + } + + + + private void sortAppList( List shortcutInfoBeanList){ + List shortAppBeanList = AppManager.getInstance().getShortAppBeanAppByCategory(); + Map tmpMapData = new HashMap<>(); + + for (ShortAppBean shortAppBean:shortAppBeanList){ + tmpMapData.put(shortAppBean.getPackageName(),shortAppBean); + } + + for (int i=0;i> datas = mStatusLoader.getStatusData(); + if(ad==null){ + ad = new StatusAdapter(getActivity(), datas, R.layout.homelist_item, + new String[] {StatusLoader.ICON}, + new int[] {R.id.item_type, 0, 0}); + lv_status.setAdapter(ad); + }else { + ad.addDatas(datas); + } + } + }); + + } + + + + private View.OnClickListener onClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + ADSWindowManager.getInstance().stopVideo(); + + if(v.getId()==R.id.layout_video){ + LogUtils.loge("go to video"); + doneEvents(new MessageEvent(VideoFragment.ACTION)); + }else if(v.getId()==R.id.layout_recommend){ + LogUtils.loge("go to recommend"); + doneEvents(new MessageEvent(RecommendFragment.ACTION)); + }else if(v.getId()==R.id.layout_music){ + LogUtils.loge("go to music"); + doneEvents(new MessageEvent(MusicFragment.ACTION)); + } +// else if(v.getId()==R.id.layout_app){ +// LogUtils.loge("go to app"); +// doneEvents(new MessageEvent(AppsFragment.ACTION)); +// }else if(v.getId()==R.id.layout_local){ +// LogUtils.loge("go to local"); +// doneEvents(new MessageEvent(LocalFragment.ACTION)); +// } + else if(v.getId()==R.id.layout_setting){ + LogUtils.loge("go to setting"); + doneEvents(new MessageEvent("com.android.tv.system.settings")); + + + } + + + } + }; + + + private void showCustomApps(){ + cuttentModel = MODEL_CUSTOM; + LogUtils.loge("coustom_view.getHeight():"+coustom_view.getLayoutParams().height); + TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f,0.0f, (float)(0 - coustom_view.getLayoutParams().height)); + translateAnimation.setDuration(300); + translateAnimation.setFillAfter(true); + content_view.startAnimation(translateAnimation); + + coustom_view.setVisibility(View.VISIBLE); + TranslateAnimation exitTransAnim = new TranslateAnimation(0.0f, 0.0f,coustom_view.getY()+coustom_view.getLayoutParams().height, 0); + exitTransAnim.setDuration(300); + translateAnimation.setFillAfter(true); + coustom_view.startAnimation(exitTransAnim); + loadCustomAppList(); + coustom_view.requestFocus(); + + } + + + private void dismissCustomApp(){ + cuttentModel = MODEL_NORMAL; + LogUtils.loge("coustom_view.getHeight():"+coustom_view.getLayoutParams().height); + TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f,(float)(0 - coustom_view.getLayoutParams().height),0.0f); + translateAnimation.setDuration(300); + translateAnimation.setFillAfter(true); + content_view.startAnimation(translateAnimation); + TranslateAnimation exitTransAnim = new TranslateAnimation(0.0f, 0.0f, 0,coustom_view.getY()+coustom_view.getLayoutParams().height); + exitTransAnim.setDuration(300); + translateAnimation.setFillAfter(true); + coustom_view.startAnimation(exitTransAnim); + coustom_view.setVisibility(View.GONE); + loadShortAppList(); + } + + private boolean isShowCustomApp(){ + return cuttentModel==MODEL_NORMAL?false:true; + } + + @Override + public void onSelectItem(ShortAppBean shortAppInfoBean, int sleectIndex) { + if(shortAppInfoBean.getItemType()==0){ + LogUtils.loge("open app custom view"); + if(!isShowCustomApp()){ + showCustomApps(); + } + }else { + LogUtils.loge("open app package name is "+shortAppInfoBean.getPackageName()); + + } + + } + + + protected void selectAppByCategory(AppBean appBean,int Category){ + AppManager.getInstance().selectAppByCategory(appBean,Category); + + } + + + + Player.Listener mediaListener = new Player.Listener() { + @Override + public void onPlaybackStateChanged(int playbackState) { + LogUtils.loge("onPlaybackStateChanged:"+playbackState); + + if(playbackState == Player.STATE_ENDED){ + + + } + + } + }; + + + /*** + * 创建有资源可播放的广告窗口 + * @return + */ + private void bindAdsWindowMultiView(){ + List adsInfoBeanList= ADManager.getInstance().getADInfoListByadType(ADManager.ADTYPE_VIDEO); + List multiViewArrayList = new ArrayList<>(); + for (int i=0;i appBeanList = (List) data; + for (MusicAppBean musicAppBean:appBeanList){ + LogUtils.loge("app is collect"+musicAppBean.getPackageName()); + collectAppMap.put(musicAppBean.getPackageName(),musicAppBean.getPackageName()); + } + appBeanList.add(new MusicAppBean()); + mMusicAppAdapter.addDatas(appBeanList); + } + super.onResult(data); + } + + @Override + protected void refreshUi() { + LogUtils.loge("refreshUi===>"); + loadAppInfoByCategory(AppManager.CATEGORY_MUSIC); + } + + @Override + protected void onSelectCustomApp(AppBean appBean,int index) { + + if(appBean.getSelect()==0){ + appBean.setSelect(1); + collectAppMap.put(appBean.getPackageName(),appBean.getPackageName()); + }else { + appBean.setSelect(0); + collectAppMap.remove(appBean.getPackageName()); + } + AppManager.getInstance().selectAppByCategory(appBean,AppManager.CATEGORY_MUSIC); + mCustomAppAdapter.notifyItemChanged(index); + } + + + + @Override + protected void initData() { + loadAppInfoByCategory(AppManager.CATEGORY_MUSIC); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + + LogUtils.loge("onKeyDown==>"+keyCode); + return super.onKeyDown(keyCode, event); + } + + + @Override + protected void toNextPage() { + doneEvents(new MessageEvent(LocalFragment.ACTION)); + } + + @Override + protected void toPreviousPage() { + doneEvents(new MessageEvent(AppsFragment.ACTION)); + + } + + + @Override + public void onResumeFragment(MessageEvent event) { + super.onResumeFragment(event); + loadAppInfoByCategory(AppManager.CATEGORY_MUSIC);//重新加载数据 + } + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/fragment/RecommendFragment.java b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/RecommendFragment.java new file mode 100644 index 0000000..ac2ee1a --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/RecommendFragment.java @@ -0,0 +1,121 @@ +package com.ik.mboxlauncher.ui.fragment; + +import android.content.Intent; +import android.view.KeyEvent; +import android.view.View; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; + +import com.android.database.lib.AppBean; +import com.android.database.lib.RecommendAppBean; +import com.android.eventbaus.MessageEvent; +import com.android.nebulasdk.AppManager; +import com.android.util.IntentUtil; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; +import com.ik.mboxlauncher.ui.adapter.RecommendAppAdapter; + +import java.util.List; + +public class RecommendFragment extends CategoryFragment { + + public static final String ACTION="com.ik.mboxlauncher.ui.fragment.RecommendFragment"; + private RecommendAppAdapter mRecommendAppAdapter; + @Override + protected void initView(View view) { + mCategory=AppManager.CATEGORY_RECOMMEND; + super.initView(view); + img_logo.setImageResource(R.drawable.recommend); + tv_title.setText(R.string.str_recommend); + setTabType(RECOMMEND_CATEGORY); + + if(mRecommendAppAdapter==null){ + mRecommendAppAdapter = new RecommendAppAdapter(getActivity(),AppManager.CATEGORY_RECOMMEND); + mRecommendAppAdapter.setmOnSelectItemListener(new RecommendAppAdapter.OnSelectItemListener() { + @Override + public void onSelectItem(RecommendAppBean shortAppInfoBean, int sleectIndex) { + LogUtils.loge("sleectIndex|getItemType==>"+sleectIndex+"|"+shortAppInfoBean.getItemType()); + if(shortAppInfoBean.getItemType()==0){ + if(!isShowCustomApp()) { + showCustomApps(); + } + }else { + LogUtils.loge("open app, package is "+shortAppInfoBean.getPackageName()); + IntentUtil.startApp(getActivity(),shortAppInfoBean.getPackageName(),getResources().getString(R.string.app_not_exist)); + + } + } + }); + } + GridLayoutManager customLayoutManager = new GridLayoutManager(view.getContext(), 6); + gv_category_apps.setLayoutManager(customLayoutManager); + gv_category_apps.setAdapter(mRecommendAppAdapter); + } + + + @Override + public void onResult(Object data) { + if(data!=null){ + collectAppMap.clear(); + List appBeanList = (List) data; + for (RecommendAppBean recommendAppBean:appBeanList){ + LogUtils.loge("app is collect"+recommendAppBean.getPackageName()); + collectAppMap.put(recommendAppBean.getPackageName(),recommendAppBean.getPackageName()); + } + appBeanList.add(new RecommendAppBean()); + mRecommendAppAdapter.addDatas(appBeanList); + } + super.onResult(data); + } + + @Override + protected void refreshUi() { + LogUtils.loge("refreshUi===>"); + loadAppInfoByCategory(AppManager.CATEGORY_RECOMMEND); + } + + @Override + protected void onSelectCustomApp(AppBean appBean,int index) { + + if(appBean.getSelect()==0){ + appBean.setSelect(1); + collectAppMap.put(appBean.getPackageName(),appBean.getPackageName()); + }else { + appBean.setSelect(0); + collectAppMap.remove(appBean.getPackageName()); + } + AppManager.getInstance().selectAppByCategory(appBean,AppManager.CATEGORY_RECOMMEND); + mCustomAppAdapter.notifyItemChanged(index); + } + + @Override + protected void initData() { + loadAppInfoByCategory(AppManager.CATEGORY_RECOMMEND); + } + + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + return super.onKeyDown(keyCode, event); + } + + + + @Override + protected void toNextPage() { + doneEvents(new MessageEvent(AppsFragment.ACTION)); + } + + @Override + protected void toPreviousPage() { + doneEvents(new MessageEvent(VideoFragment.ACTION)); + } + + + @Override + public void onResumeFragment(MessageEvent event) { + super.onResumeFragment(event); + loadAppInfoByCategory(AppManager.CATEGORY_RECOMMEND);//重新加载数据 + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/ui/fragment/VideoFragment.java b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/VideoFragment.java new file mode 100644 index 0000000..5af5f19 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/ui/fragment/VideoFragment.java @@ -0,0 +1,124 @@ +package com.ik.mboxlauncher.ui.fragment; + +import android.content.Intent; +import android.view.KeyEvent; +import android.view.View; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; + +import com.android.database.lib.AppBean; +import com.android.database.lib.VideoAppBean; +import com.android.eventbaus.MessageEvent; +import com.android.nebulasdk.AppManager; +import com.android.util.IntentUtil; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; +import com.ik.mboxlauncher.ui.adapter.VideoAppAdapter; + +import java.util.List; + +public class VideoFragment extends CategoryFragment { + + public static final String ACTION="com.ik.mboxlauncher.ui.fragment.VideoFragment"; + private VideoAppAdapter mVideoAppAdapter = null; + @Override + protected void initView(View view) { + mCategory=AppManager.CATEGORY_VIDEO; + super.initView(view); + img_logo.setImageResource(R.drawable.video); + tv_title.setText(R.string.str_video); + setTabType(VIDEO_CATEGORY); + + if(mVideoAppAdapter==null){ + mVideoAppAdapter = new VideoAppAdapter(getActivity(),AppManager.CATEGORY_VIDEO); + mVideoAppAdapter.setmOnSelectItemListener(new VideoAppAdapter.OnSelectItemListener() { + @Override + public void onSelectItem(VideoAppBean shortAppInfoBean, int sleectIndex) { + if(shortAppInfoBean.getItemType()==0){ + if(!isShowCustomApp()) { + showCustomApps(); + } + }else { + LogUtils.loge("open app, package is "+shortAppInfoBean.getPackageName()); + IntentUtil.startApp(getActivity(),shortAppInfoBean.getPackageName(),getResources().getString(R.string.app_not_exist)); + + } + } + }); + } + + GridLayoutManager layoutManager = new GridLayoutManager(view.getContext(), 6); + gv_category_apps.setLayoutManager(layoutManager); + gv_category_apps.setAdapter(mVideoAppAdapter); + } + + + @Override + public void onResult(Object data) { + if(data!=null){ + collectAppMap.clear(); + List appBeanList = (List) data; + for (VideoAppBean videoAppBean:appBeanList){ + LogUtils.loge("app is collect"+videoAppBean.getPackageName()); + collectAppMap.put(videoAppBean.getPackageName(),videoAppBean.getPackageName()); + } + + appBeanList.add(new VideoAppBean()); + mVideoAppAdapter.addDatas(appBeanList); + } + super.onResult(data); + } + + @Override + protected void refreshUi() { + loadAppInfoByCategory(AppManager.CATEGORY_VIDEO); + + } + + @Override + protected void onSelectCustomApp(AppBean appBean,int index) { + + if(appBean.getSelect()==0){ + appBean.setSelect(1); + collectAppMap.put(appBean.getPackageName(),appBean.getPackageName()); + }else { + appBean.setSelect(0); + collectAppMap.remove(appBean.getPackageName()); + } + AppManager.getInstance().selectAppByCategory(appBean,AppManager.CATEGORY_VIDEO); + mCustomAppAdapter.notifyItemChanged(index); + } + + @Override + protected void initData() { + loadAppInfoByCategory(AppManager.CATEGORY_VIDEO); + } + + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + + return super.onKeyDown(keyCode, event); + + } + + + + @Override + protected void toNextPage() { + doneEvents(new MessageEvent(RecommendFragment.ACTION)); + } + + @Override + protected void toPreviousPage() { + + } + + + @Override + public void onResumeFragment(MessageEvent event) { + super.onResumeFragment(event); + loadAppInfoByCategory(AppManager.CATEGORY_VIDEO);//重新加载数据 + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/AdMultiView.java b/app/src/main/java/com/ik/mboxlauncher/view/AdMultiView.java new file mode 100644 index 0000000..b6af690 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/AdMultiView.java @@ -0,0 +1,484 @@ +package com.ik.mboxlauncher.view; + +import android.animation.ValueAnimator; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Outline; +import android.graphics.Rect; +import android.os.Build; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewOutlineProvider; +import android.view.animation.Animation; +import android.view.animation.ScaleAnimation; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.media3.common.Player; + +import com.android.util.LogUtils; +import com.bumptech.glide.Glide; +import com.ik.mboxlauncher.R; +import com.seraphic.ad.AdPlayManager; +import com.seraphic.ad.AdStateListener; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class AdMultiView extends MultiView { + private Context mContext; + private View mView; + private ImageView img_view; + private TextView tx_view; + private long animDuration = 50; + private View mMultiInsideLayout; + private ViewGroup mAdRootView; + private AdPlayManager mAdPlayManager; + private ViewGroup mFullRootView; + private boolean isFullAdShow; + private int mWidth = 0; + private int mHeight = 0; + + private int oldMarginstart=0; + private int oldMargintop=0; + + private int mAdState = -1; + + public AdMultiView(@NonNull Context context) { + super(context); + } + + public AdMultiView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + + } + + public AdMultiView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + } + + public AdMultiView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + public void initView(Context context, AttributeSet attrs){ + mContext = context; + LayoutInflater inflater = LayoutInflater.from(context); + mView = inflater.inflate(R.layout.ad_multi_layout,this); + tx_view = mView.findViewById(R.id.tx_view); + mMultiInsideLayout = mView.findViewById(R.id.multi_inside); + mAdRootView = mView.findViewById(R.id.ad_root); + img_view = mView.findViewById(R.id.img_view); + mView.findViewById(R.id.tx_view).setVisibility(View.INVISIBLE); + if(attrs!=null){ + TypedArray a= context.getTheme().obtainStyledAttributes(attrs,R.styleable.AdMultiView,0,0); + try { + + int titleResId = a.getResourceId(R.styleable.AdMultiView_adMultiViewTitle,-1); + int imageResId = a.getResourceId(R.styleable.AdMultiView_adMultiViewImage,-1); + + if(titleResId!=-1){ + tx_view.setText(titleResId); + tx_view.setVisibility(View.VISIBLE); + } else { + tx_view.setVisibility(View.INVISIBLE); + } + if(imageResId!=-1){ + img_view.setImageResource(imageResId); + } + + }catch (Exception e){ + e.printStackTrace(); + } + } + mMultiInsideLayout.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(4, 4, view.getWidth()-4, view.getHeight()-4, 20); + } + }); + mMultiInsideLayout.setClipToOutline(true); + hookWebView(); + } + + @Override + public void onVideoRestart(String uri) { + startAd(); + } + + @Override + public void onImageRestart(String uri) { + + } + + + @Override + public void onImageRestartLocal(String path) { + if(path==null){ + return; + } + img_view.setVisibility(VISIBLE); + File tmpfile= new File(path); + LogUtils.loge("AdMultiView tmpfile===>"+tmpfile.exists()); + if(tmpfile.exists()) { + Glide.with(mContext).load(tmpfile).into(img_view); + } + + } + + @Override + public void loadIamgeRes(String uri, int defaultImageId) { + + } + + @Override + public void loadDefaultImage(int resId) { + img_view.setImageResource(resId); + } + + @Override + public void resetView() { + //TODO 如果无需响应用户操作取消广告(即:广告可点击),删掉下方一行代码 +// stopAd(); + } + + @Override + public void stopView() { + LogUtils.loge( "stopView=====>"); + stopAd(); + if(mFullRootView.getVisibility()==VISIBLE){ + mFullRootView.setVisibility(GONE); + } + } + + @Override + public void releaseView() { + + } + + @Override + public void pauseView() { + + } + + @Override + public boolean isAdPlaying() { + return mAdState == AdStateListener.AD_PLAYING + || mAdState == AdStateListener.AD_LOADING + || mAdState == AdStateListener.AD_LOADED; + } + + + public void setFullRooView(ViewGroup fullRooView){ + mFullRootView = fullRooView; + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + if(mWidth == 0 || mHeight == 0) { + RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); + mWidth = getWidth(); + mHeight = getHeight(); + oldMarginstart =layoutParams.leftMargin; + oldMargintop =layoutParams.topMargin; + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + stopAd(); + } + + @SuppressLint("SoonBlockedPrivateApi") + private void hookWebView() { + int sdkInt = Build.VERSION.SDK_INT; + try { + Class factoryClass = Class.forName("android.webkit.WebViewFactory"); + Field field = factoryClass.getDeclaredField("sProviderInstance"); + field.setAccessible(true); + Object sProviderInstance = field.get(null); + if (sProviderInstance != null) { + LogUtils.logi("sProviderInstance isn't null"); + return; + } + Method getProviderClassMethod = null; + if (sdkInt > 22) { + getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass"); + } else if (sdkInt == 22) { + getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass"); + } else { + LogUtils.logi("Don't need to Hook WebView"); + return; + } + getProviderClassMethod.setAccessible(true); + Class factoryProviderClass = (Class) getProviderClassMethod.invoke(factoryClass); + Class delegateClass = Class.forName("android.webkit.WebViewDelegate"); + Constructor delegateConstructor = delegateClass.getDeclaredConstructor(); + delegateConstructor.setAccessible(true); + if (sdkInt < 26) { //低于Android O版本 + Constructor providerConstructor = factoryProviderClass.getConstructor(delegateClass); + if (providerConstructor != null) { + providerConstructor.setAccessible(true); + sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance()); + } + } else { + Field chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD"); + chromiumMethodName.setAccessible(true); + String chromiumMethodNameStr = (String) chromiumMethodName.get(null); + if (chromiumMethodNameStr == null) { + chromiumMethodNameStr = "create"; + } + Method staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass); + if (staticFactory != null) { + sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance()); + } + } + + if (sProviderInstance != null) { + field.set("sProviderInstance", sProviderInstance); + LogUtils.logi("can use webview"); + } else { + LogUtils.logi("can not use webview"); + } + } catch (Exception e) { + } + } + + private void startAd(){ + if(mAdPlayManager != null){ + stopAd(); + } + mAdPlayManager = new AdPlayManager(mContext, AdPlayManager.TYPE_WITH_CONTAINER, + 0, adstate -> { + if(mMultiViewListener != null) { + int playState = Player.STATE_IDLE; + switch (adstate){ + case AdStateListener.AD_LOADING: + playState = Player.STATE_BUFFERING; + break; + case AdStateListener.AD_LOADED: + case AdStateListener.AD_PLAYING: + playState = Player.STATE_READY; + break; + case AdStateListener.AD_ERROR: + playState = adstate; + break; + case AdStateListener.AD_COMPLETE_ALL: + playState = Player.STATE_ENDED; + break; + } + LogUtils.loge("AdMultiView adstate ===>"+adstate); + if((mAdState == -1 || mAdState != adstate) && playState != Player.STATE_IDLE) { + mMultiViewListener.onPlaybackStateChanged(getId(), playState); + } + } + mAdState = adstate; + + if(adstate == AdStateListener.AD_COMPLETE_ALL||adstate == AdStateListener.AD_ERROR){ + if(isFullAdShow){ + isFullAdShow = false; + requestFocus(); + } + stopAd(); + } + }); //position 必填 + mAdPlayManager.setAdFullRootView(mFullRootView);//设置全屏的 ad root + if(isFocused()) {//焦点在当前view时,显示back提示 + mAdPlayManager.setNeedCancelTips(true); + } + mAdPlayManager.startAd(mAdRootView,0); + } + @Override + public void stopAd() { + LogUtils.loge( "stopAd=====>"); + if (mAdPlayManager != null) { + mAdPlayManager.stopAd(); + mAdPlayManager = null; + } + } + + @Override + public boolean onAdViewClick(){ + boolean isNeed = false; + if (mAdPlayManager != null) { + isNeed = mAdPlayManager.onAdViewClick(); + } + isFullAdShow = isNeed; + return isNeed; + } + public boolean onAdBackClick(){ + boolean isNeed = false; + //NOTE: 如果希望全局按back键取消广告,可以移除焦点判断 + if (isFocused() && mAdPlayManager != null) { + isNeed = mAdPlayManager.onAdBackClick(); + } + return isNeed; + } + + private boolean mGainFocus=false; + +// @Override +// protected void onFocusChanged(boolean gainFocus, int direction, @Nullable Rect previouslyFocusedRect) { +// super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); +// mGainFocus = gainFocus; +// +// if (gainFocus) { +// if(mAdPlayManager != null) { +// mAdPlayManager.setNeedCancelTips(true); +// } +// setBackgroundResource(R.drawable.app_item_border); +// setTranslationZ(10); +// setElevation(10); +// +// scaleView(1.05f); +// +//// ScaleAnimation anim = new ScaleAnimation(1f, 1.1f, 1f, 1.1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); +//// anim.setZAdjustment(Animation.ZORDER_TOP); +//// anim.setDuration(animDuration); +//// anim.setFillAfter(true); +//// this.startAnimation(anim); +// this.bringToFront(); +// } else { +// if(mAdPlayManager != null) { +// mAdPlayManager.setNeedCancelTips(false); +// } +// setBackgroundResource(R.color.transparent_background); +// setTranslationZ(0); +// setElevation(0); +// scaleView(1.0f); +//// ScaleAnimation anim = new ScaleAnimation(1.1f, 1f, 1.1f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); +//// anim.setZAdjustment(Animation.ZORDER_TOP); +//// anim.setDuration(animDuration); +//// anim.setFillAfter(true); +//// this.startAnimation(anim); +// } +// } + + @Override + protected void onFocusChanged(boolean gainFocus, int direction, @Nullable Rect previouslyFocusedRect) { + super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); +// int width = getWidth(); +// int height = getHeight(); + mGainFocus = gainFocus; + if(gainFocus){ + if(mAdPlayManager != null) { + mAdPlayManager.setNeedCancelTips(true); + } + setBackgroundResource(R.drawable.app_item_border); + setTranslationZ(8); + setElevation(8); + ValueAnimator animator = ValueAnimator.ofFloat(1f,1.1f); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(@NonNull ValueAnimator valueAnimator) { + float scale = (float) valueAnimator.getAnimatedValue(); +// RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); +// layoutParams.height = (int) (height*scale); +// layoutParams.width = (int) (width*scale); +// setLayoutParams(layoutParams); +// setScaleWithLayoutd(scale); + setScaleWithLayoutd(scale); + invalidate(); + } + }); + animator.setDuration(animDuration); + animator.start(); + this.bringToFront(); + }else { + if(mAdPlayManager != null) { + mAdPlayManager.setNeedCancelTips(false); + } + setBackgroundResource(R.color.transparent_background); + setTranslationZ(0); + setElevation(0); + ValueAnimator animator = ValueAnimator.ofFloat(1.1f, 1f); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(@NonNull ValueAnimator valueAnimator) { + float scale = (float) valueAnimator.getAnimatedValue(); +// RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); +// layoutParams.height = (int) (height*scale); +// layoutParams.width = (int) (width*scale); +// if(layoutParams.height < mHeight || layoutParams.width < mWidth){ +// layoutParams.height = mHeight; +// layoutParams.width = mWidth; +// } +// setLayoutParams(layoutParams); +// setScaleWithLayoutd(scale); + setScaleWithLayoutd(scale); + invalidate(); + } + }); + animator.setDuration(animDuration); + animator.start(); + } + } + + + // 缩放方法 + public void scaleView(float scale) { + setScaleX(scale); + setScaleY(scale); + setScaleWithLayoutd(scale); + invalidate(); // 可选,通常不需要 + } + + + // 或者如果需要同时改变布局大小 + public void setScaleWithLayoutd(float scale) { + RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams(); + int newWidth = (int) (mWidth * scale); + int newHeight = (int) (mHeight * scale); + + // 调整margin保持中心位置 + lp.leftMargin -= (newWidth - lp.width) / 2; + lp.topMargin -= (newHeight - lp.height) / 2; + + lp.width = newWidth; + lp.height = newHeight; + setLayoutParams(lp); + } + +// public void setScaleWithLayouts(float scale) { +// RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams(); +// // 调整margin保持中心位置 +// lp.leftMargin -= (mWidth - lp.width) / 2; +// lp.topMargin -= (mWidth - lp.height) / 2; +// lp.width = mWidth; +// lp.height = mWidth; +// setLayoutParams(lp); +// } + + + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + LogUtils.loge("AdMultiView onKeyDown==>"+keyCode); + switch (keyCode){ + case KeyEvent.KEYCODE_BACK: + if(mGainFocus){ + onAdBackClick(); + return true; + } + break; + + + } + + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/CountdownTimeTextView.java b/app/src/main/java/com/ik/mboxlauncher/view/CountdownTimeTextView.java new file mode 100644 index 0000000..b43d62d --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/CountdownTimeTextView.java @@ -0,0 +1,138 @@ +package com.ik.mboxlauncher.view; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.android.util.DateUtil; + + +//时间的textView +@SuppressLint("AppCompatCustomView") +public class CountdownTimeTextView extends TextView { + + /*** + * 倒计时时间 + */ + private static final int COUNTDOWN_TIME=10; + private static int CURRENT_COUNTDOWN_TIME=COUNTDOWN_TIME; + + + private Handler handler = new Handler(){ + @Override + public void handleMessage(@NonNull Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 0: + setText(CURRENT_COUNTDOWN_TIME+" Second"); + break; + case 1: + if(mTextUiCallBack!=null){ + mTextUiCallBack.onEndCallback(); + } + break; + } + } + }; + + public CountdownTimeTextView(Context context) { + super(context); + } + + public CountdownTimeTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CountdownTimeTextView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + public CountdownTimeTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public void starTimeUi(TextUiCallBack callBack){ + this.mTextUiCallBack = callBack; + if(isRunning==false) { + countdownTimeThread.start(); + } +// handler.post(timeRunnable); + } + + public void cancelTimeUi(){ + isRunning=false; + } + + private boolean isRunning=false; + +// Runnable timeRunnable = new Runnable() { +// @Override +// public void run() { +// +// +// +// CURRENT_COUNTDOWN_TIME--; +// Log.i("liu","CURRENT_COUNTDOWN_TIME:"+CURRENT_COUNTDOWN_TIME); +// if(CURRENT_COUNTDOWN_TIME<0){ +// CURRENT_COUNTDOWN_TIME = COUNTDOWN_TIME; +// if(mTextUiCallBack!=null){ +// mTextUiCallBack.onEndCallback(); +// } +// }else { +// setText(CURRENT_COUNTDOWN_TIME+" Second"); +// handler.postDelayed(this,1000); +// } +// +// } +// }; + + + Thread countdownTimeThread = new Thread(){ + @Override + public void run() { + super.run(); + isRunning =true; + while (CURRENT_COUNTDOWN_TIME>-1){ + if(!isRunning){ + break; + } + handler.sendEmptyMessage(0); + try { + sleep(1000*1); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + CURRENT_COUNTDOWN_TIME--; + Log.i("liu","CURRENT_COUNTDOWN_TIME:"+CURRENT_COUNTDOWN_TIME); + + + } + + handler.sendEmptyMessage(1); + + } + }; + + + private TextUiCallBack mTextUiCallBack; + + public TextUiCallBack getmTextUiCallBack() { + return mTextUiCallBack; + } + + public void setmTextUiCallBack(TextUiCallBack mTextUiCallBack) { + this.mTextUiCallBack = mTextUiCallBack; + } + + public interface TextUiCallBack{ + public void onEndCallback(); + } + + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/CustomRecyclerView.java b/app/src/main/java/com/ik/mboxlauncher/view/CustomRecyclerView.java new file mode 100644 index 0000000..198e637 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/CustomRecyclerView.java @@ -0,0 +1,270 @@ +package com.ik.mboxlauncher.view; + + +import android.content.Context; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.Log; +import android.view.FocusFinder; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; + + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearSmoothScroller; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.util.GsonUtil; +import com.android.util.LogUtils; +import com.google.android.gms.common.util.JsonUtils; + +import java.util.ArrayList; + +public class CustomRecyclerView extends RecyclerView { + private static final String TAG = CustomRecyclerView.class.getSimpleName(); + //是否可以纵向移出 + private boolean mCanFocusOutVertical = false; + //是否可以横向移出 + private boolean mCanFocusOutHorizontal = true; + //焦点移出recyclerview的事件监听 + private FocusLostListener mFocusLostListener; + //焦点移入recyclerview的事件监听 + private FocusGainListener mFocusGainListener; + //默认第一次选中第一个位置 + private int mCurrentFocusPosition = 0; + + public CustomRecyclerView(Context context) { + this(context, null); + } + + public CustomRecyclerView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public CustomRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); + setChildrenDrawingOrderEnabled(true); + setItemAnimator(null); + this.setFocusable(true); + addItemDecoration(new ItemDecoration() { + @Override + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull State state) { + outRect.left = 1; + outRect.right = 1; + outRect.bottom = 1; + outRect.top = 1; + } + }); + } + + public boolean isCanFocusOutVertical() { + return mCanFocusOutVertical; + } + + public void setCanFocusOutVertical(boolean canFocusOutVertical) { + mCanFocusOutVertical = canFocusOutVertical; + } + + public boolean isCanFocusOutHorizontal() { + return mCanFocusOutHorizontal; + } + + public void setCanFocusOutHorizontal(boolean canFocusOutHorizontal) { + mCanFocusOutHorizontal = canFocusOutHorizontal; + } + + @Override + public View focusSearch(int direction) { + return super.focusSearch(direction); + } + + //覆写focusSearch寻焦策略 + @Override + public View focusSearch(View focused, int direction) { + View view = super.focusSearch(focused, direction); + + if (focused == null) { + return view; + } + if (view != null) { + //该方法返回焦点view所在的父view,如果是在recyclerview之外,就会是null.所以根据是否是null,来判断是否是移出了recyclerview + View nextFocusItemView = findContainingItemView(view); + LogUtils.loge("nextFocusItemView===>"+nextFocusItemView); + if (nextFocusItemView == null) { + if (!mCanFocusOutVertical && (direction == View.FOCUS_DOWN || direction == View.FOCUS_UP)) { + //屏蔽焦点纵向移出recyclerview + LogUtils.loge("屏蔽焦点纵向移出recyclerview"); + return focused; + } + if (!mCanFocusOutHorizontal && (direction == View.FOCUS_LEFT || direction == View.FOCUS_RIGHT)) { + //屏蔽焦点横向移出recyclerview + LogUtils.loge("屏蔽焦点横向移出recyclerview"); + return focused; + } + + LogUtils.loge("移出了recyclerview"); + //调用移出的监听 + if (mFocusLostListener != null) { + mFocusLostListener.onFocusLost(focused, direction); + } + return view; + } + } + return view; + } + + public void setFocusLostListener(FocusLostListener focusLostListener) { + this.mFocusLostListener = focusLostListener; + } + + public interface FocusLostListener { + void onFocusLost(View lastFocusChild, int direction); + } + + public void setGainFocusListener(FocusGainListener focusListener) { + this.mFocusGainListener = focusListener; + } + + public interface FocusGainListener { + void onFocusGain(View child, View focued); + } + + @Override + public void requestChildFocus(View child, View focused) { + if (!hasFocus()) { + //recyclerview 子view 重新获取焦点,调用移入焦点的事件监听 + if (mFocusGainListener != null) { + mFocusGainListener.onFocusGain(child, focused); + } + } + super.requestChildFocus(child, focused);//执行过super.requestChildFocus之后hasFocus会变成true + mCurrentFocusPosition = getChildViewHolder(child).getAdapterPosition(); + + + + } + + //实现焦点记忆的关键代码 + @Override + public void addFocusables(ArrayList views, int direction, int focusableMode) { + try { + View view = null; + if (this.hasFocus() || mCurrentFocusPosition < 0 || (view = getLayoutManager().findViewByPosition(mCurrentFocusPosition)) == null) { + super.addFocusables(views, direction, focusableMode); + } else if (view.isFocusable()) { +//将当前的view放到Focusable views列表中,再次移入焦点时会取到该view,实现焦点记忆功能 + views.add(view); + } else { + super.addFocusables(views, direction, focusableMode); + } + } catch (Exception e) { + e.printStackTrace(); + } + + + } + + /** + * 控制当前焦点最后绘制,防止焦点放大后被遮挡 + * 原顺序123456789,当4是focus时,绘制顺序变为123567894 + * + * @param childCount + * @param i + * @return + */ + @Override + protected int getChildDrawingOrder(int childCount, int i) { + View focusedChild = getFocusedChild(); + if (focusedChild == null) { + return super.getChildDrawingOrder(childCount, i); + } else { + int index = indexOfChild(focusedChild); + // testing!!!!!! MyRecyclerView list log +// Log.i(TAG, " index = " + index + ",i=" + i + ",count=" + childCount); + if (i == childCount - 1) { + return index; + } + if (i < index) { + return i; + } + return i + 1; + } + } + + + + + + private long mLastKeyDownTime=0; + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_DOWN) { + +// int keyCode = event.getKeyCode(); +// if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_UP) { +// long current = System.currentTimeMillis(); +// boolean res; +// if (current - mLastKeyDownTime < 150) { +// res = true; +// } else { +// res = super.onKeyDown(keyCode, event); +// mLastKeyDownTime = current; +// } +// return res; +// } +// + +// View focusedView = getFocusedChild(); // 获取当前获得焦点的view +// View nextFocusView; +// try { +// if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { +// // 通过findNextFocus获取下一个需要得到焦点的view +// nextFocusView = FocusFinder.getInstance().findNextFocus(this, focusedView, View.FOCUS_DOWN); +// } else { +// // 通过findNextFocus获取下一个需要得到焦点的view +// nextFocusView = FocusFinder.getInstance().findNextFocus(this, focusedView, View.FOCUS_UP); +// } +// +// +// LogUtils.loge("nextFocusView===>"+nextFocusView); +// +// } catch (Exception e) { +// nextFocusView = null; +// } +// +// // 如果获取失败(也就是说需要交给系统来处理焦点, 消耗掉事件,不让系统处理, 并让先前获取焦点的view获取焦点) +// if (nextFocusView == null) { +// focusedView.requestFocus(); +// return true; +// +// } +// } +// } + } + + return super.dispatchKeyEvent(event); + } + + + + LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(getContext()){ + + @Override + protected int getHorizontalSnapPreference() { + return LinearSmoothScroller.SNAP_TO_START; + } + + @Override + protected int getVerticalSnapPreference() { + return LinearSmoothScroller.SNAP_TO_START; + } + }; + + public void scrollToPositionWithOffset(int position){ + linearSmoothScroller.setTargetPosition(position); + getLayoutManager().startSmoothScroll(linearSmoothScroller); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/CustomRecyclerViewer.java b/app/src/main/java/com/ik/mboxlauncher/view/CustomRecyclerViewer.java new file mode 100644 index 0000000..a928fbe --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/CustomRecyclerViewer.java @@ -0,0 +1,290 @@ +package com.ik.mboxlauncher.view; + + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearSmoothScroller; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.util.ArrayList; + +public class CustomRecyclerViewer extends RecyclerView { + private static final String TAG = CustomRecyclerViewer.class.getSimpleName(); + private int offset = 0; + //是否可以纵向移出 + private boolean mCanFocusOutVertical = false; + //是否可以横向移出 + private boolean mCanFocusOutHorizontal = true; + //焦点移出recyclerview的事件监听 + private FocusLostListener mFocusLostListener; + + + + // 移动到边界的监听 + private FocusOnBoundaryListener mFocusOnBoundaryListener; + //焦点移入recyclerview的事件监听 + private FocusGainListener mFocusGainListener; + //默认第一次选中第一个位置 + private int mCurrentFocusPosition = 0; + + public CustomRecyclerViewer(Context context) { + this(context, null); + } + + public CustomRecyclerViewer(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public CustomRecyclerViewer(Context context, @Nullable AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); + setChildrenDrawingOrderEnabled(true); + setItemAnimator(null); + this.setFocusable(true); + if(attrs!=null){ + TypedArray a= context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomRecyclerViewer,0,0); + try { + offset = a.getDimensionPixelOffset(R.styleable.CustomRecyclerViewer_itemOffsets,0); + }catch (Exception e){ + e.printStackTrace(); + + } + } + addItemDecoration(new ItemDecoration() { + @Override + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull State state) { + outRect.left = offset; + outRect.right = offset; + outRect.bottom = offset; + outRect.top = offset; + } + }); + } + + public boolean isCanFocusOutVertical() { + return mCanFocusOutVertical; + } + + public void setCanFocusOutVertical(boolean canFocusOutVertical) { + mCanFocusOutVertical = canFocusOutVertical; + } + + public boolean isCanFocusOutHorizontal() { + return mCanFocusOutHorizontal; + } + + public void setCanFocusOutHorizontal(boolean canFocusOutHorizontal) { + mCanFocusOutHorizontal = canFocusOutHorizontal; + } + + @Override + public View focusSearch(int direction) { + return super.focusSearch(direction); + } + + //覆写focusSearch寻焦策略 + @Override + public View focusSearch(View focused, int direction) { + View view = super.focusSearch(focused, direction); + + LogUtils.loge("view===>"+view+"|"+focused); + if (focused == null) { + return view; + } + if (view != null) { + //该方法返回焦点view所在的父view,如果是在recyclerview之外,就会是null.所以根据是否是null,来判断是否是移出了recyclerview + View nextFocusItemView = findContainingItemView(view); + LogUtils.loge("nextFocusItemView===>"+nextFocusItemView); + if (nextFocusItemView == null) { + if (!mCanFocusOutVertical && (direction == View.FOCUS_DOWN || direction == View.FOCUS_UP)) { + //屏蔽焦点纵向移出recyclerview + return focused; + } + if (!mCanFocusOutHorizontal && (direction == View.FOCUS_LEFT || direction == View.FOCUS_RIGHT)) { + //屏蔽焦点横向移出recyclerview + return focused; + } + //调用移出的监听 + if (mFocusLostListener != null) { + mFocusLostListener.onFocusLost(focused, direction); + } + return view; + } + }else { + if(mFocusOnBoundaryListener!=null){ + mFocusOnBoundaryListener.onFocusBoundary(view,direction); + } + } + return view; + } + + public void setFocusLostListener(FocusLostListener focusLostListener) { + this.mFocusLostListener = focusLostListener; + } + public void setmFocusOnBoundaryListener(FocusOnBoundaryListener mFocusOnBoundaryListener) { + this.mFocusOnBoundaryListener = mFocusOnBoundaryListener; + } + + + + public interface FocusLostListener { + void onFocusLost(View lastFocusChild, int direction); + } + + public interface FocusOnBoundaryListener { + void onFocusBoundary(View lastFocusChild, int direction); + } + + public void setGainFocusListener(FocusGainListener focusListener) { + this.mFocusGainListener = focusListener; + } + + public interface FocusGainListener { + void onFocusGain(View child, View focued); + } + + @Override + public void requestChildFocus(View child, View focused) { + if (!hasFocus()) { + //recyclerview 子view 重新获取焦点,调用移入焦点的事件监听 + if (mFocusGainListener != null) { + mFocusGainListener.onFocusGain(child, focused); + } + } + super.requestChildFocus(child, focused);//执行过super.requestChildFocus之后hasFocus会变成true + mCurrentFocusPosition = getChildViewHolder(child).getAdapterPosition(); + } + + //实现焦点记忆的关键代码 + @Override + public void addFocusables(ArrayList views, int direction, int focusableMode) { + try { + View view = null; + if (this.hasFocus() || mCurrentFocusPosition < 0 || (view = getLayoutManager().findViewByPosition(mCurrentFocusPosition)) == null) { + super.addFocusables(views, direction, focusableMode); + } else if (view.isFocusable()) { +//将当前的view放到Focusable views列表中,再次移入焦点时会取到该view,实现焦点记忆功能 + views.add(view); + } else { + super.addFocusables(views, direction, focusableMode); + } + } catch (Exception e) { + e.printStackTrace(); + } + + + } + + /** + * 控制当前焦点最后绘制,防止焦点放大后被遮挡 + * 原顺序123456789,当4是focus时,绘制顺序变为123567894 + * + * @param childCount + * @param i + * @return + */ + @Override + protected int getChildDrawingOrder(int childCount, int i) { + View focusedChild = getFocusedChild(); + if (focusedChild == null) { + return super.getChildDrawingOrder(childCount, i); + } else { + int index = indexOfChild(focusedChild); + // testing!!!!!! MyRecyclerView list log +// Log.i(TAG, " index = " + index + ",i=" + i + ",count=" + childCount); + if (i == childCount - 1) { + return index; + } + if (i < index) { + return i; + } + return i + 1; + } + } + + + + + + private long mLastKeyDownTime=0; + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_DOWN) { + +// int keyCode = event.getKeyCode(); +// if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_UP) { +// long current = System.currentTimeMillis(); +// boolean res; +// if (current - mLastKeyDownTime < 150) { +// res = true; +// } else { +// res = super.onKeyDown(keyCode, event); +// mLastKeyDownTime = current; +// } +// return res; +// } +// + +// View focusedView = getFocusedChild(); // 获取当前获得焦点的view +// View nextFocusView; +// try { +// if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { +// // 通过findNextFocus获取下一个需要得到焦点的view +// nextFocusView = FocusFinder.getInstance().findNextFocus(this, focusedView, View.FOCUS_DOWN); +// } else { +// // 通过findNextFocus获取下一个需要得到焦点的view +// nextFocusView = FocusFinder.getInstance().findNextFocus(this, focusedView, View.FOCUS_UP); +// } +// +// +// LogUtils.loge("nextFocusView===>"+nextFocusView); +// +// } catch (Exception e) { +// nextFocusView = null; +// } +// +// // 如果获取失败(也就是说需要交给系统来处理焦点, 消耗掉事件,不让系统处理, 并让先前获取焦点的view获取焦点) +// if (nextFocusView == null) { +// focusedView.requestFocus(); +// return true; +// +// } +// } +// } + } + + return super.dispatchKeyEvent(event); + } + + + + LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(getContext()){ + + @Override + protected int getHorizontalSnapPreference() { + return LinearSmoothScroller.SNAP_TO_START; + } + + @Override + protected int getVerticalSnapPreference() { + return LinearSmoothScroller.SNAP_TO_START; + } + }; + + public void scrollToPositionWithOffset(int position){ + linearSmoothScroller.setTargetPosition(position); + getLayoutManager().startSmoothScroll(linearSmoothScroller); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/HomeMultiView.java b/app/src/main/java/com/ik/mboxlauncher/view/HomeMultiView.java new file mode 100644 index 0000000..29087d7 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/HomeMultiView.java @@ -0,0 +1,404 @@ +package com.ik.mboxlauncher.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Outline; +import android.graphics.Rect; +import android.net.Uri; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewOutlineProvider; +import android.view.animation.Animation; +import android.view.animation.ScaleAnimation; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.media3.common.MediaItem; +import androidx.media3.common.PlaybackException; +import androidx.media3.common.Player; +import androidx.media3.common.util.UnstableApi; +import androidx.media3.datasource.DataSource; +import androidx.media3.datasource.DefaultDataSource; +import androidx.media3.exoplayer.ExoPlayer; +import androidx.media3.exoplayer.ima.ImaAdsLoader; +import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; +import androidx.media3.exoplayer.source.MediaSource; +import androidx.media3.ui.PlayerView; + +import com.android.util.LogUtils; +import com.bumptech.glide.Glide; +import com.google.ads.interactivemedia.v3.api.AdEvent; +import com.ik.mboxlauncher.R; + +import java.io.File; + +import static android.os.Build.VERSION.SDK_INT; + +public class HomeMultiView extends MultiView { + + + + private static String SAMPLE_VIDEO_URL = + "https://storage.googleapis.com/gvabox/media/samples/stock.mp4"; + + private static String SAMPLE_VIDEO_URL1 = + "https://storage.googleapis.com/gvabox/media/samples/stock.mp4"; +// private static final String SAMPLE_VAST_TAG_URL = +// "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/" +// + "single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90" +// + "&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator="; + private static final String LOG_TAG = "ImaExoPlayerExample"; + + + private View mView; + private PlayerView player_view; + private ImageView img_view; + private TextView tx_view; + /**广告插件开关*/ + private boolean adsSwitch=false; + private Context mContext; + private ExoPlayer player; + private ImaAdsLoader adsLoader; + private int animDuration=50; + + private View mMultiInsideLayout; + + + public HomeMultiView(@NonNull Context context) { + super(context); + } + + public HomeMultiView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public HomeMultiView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public HomeMultiView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + + @Override + public void initView(Context context, AttributeSet attrs){ + mContext = context; + LayoutInflater inflater = LayoutInflater.from(context); + mView = inflater.inflate(R.layout.multi_layout,this); + mMultiInsideLayout = mView.findViewById(R.id.multi_inside); + player_view = mView.findViewById(R.id.player_view); + img_view = mView.findViewById(R.id.img_view); + tx_view = mView.findViewById(R.id.tx_view); + if(attrs!=null){ + TypedArray a= context.getTheme().obtainStyledAttributes(attrs,R.styleable.MultiView,0,0); + try { + int titleResId = a.getResourceId(R.styleable.MultiView_multiViewTitle,-1); + int imageResId = a.getResourceId(R.styleable.MultiView_multiViewImage,-1); + boolean adsSwitch = a.getBoolean(R.styleable.MultiView_adsSwitch,false); + if(titleResId!=-1){ + tx_view.setText(titleResId); + tx_view.setVisibility(View.VISIBLE); + } else { + tx_view.setVisibility(View.INVISIBLE); + } + + if(imageResId!=-1){ + img_view.setImageResource(imageResId); + } + + }catch (Exception e){ + e.printStackTrace(); + + } + } + mMultiInsideLayout.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(4, 4, view.getWidth()-4, view.getHeight()-4, 20); + } + }); + mMultiInsideLayout.setClipToOutline(true); + } + + @UnstableApi private void onRestart(){ + if (SDK_INT <= 23 || player == null) { + initializePlayer(); + if (player_view != null) { + player_view.onResume(); + } + } + } + + private AdEvent.AdEventListener buildAdEventListener() { + + + AdEvent.AdEventListener imaAdEventListener = + event -> { + AdEvent.AdEventType eventType = event.getType(); + if (eventType == AdEvent.AdEventType.AD_PROGRESS) { + return; + } + String log = "IMA event: " + eventType; + + LogUtils.loge(log); + }; + + return imaAdEventListener; + } + @Override + public void onVideoRestart(String uri){ + LogUtils.loge("onVideoRestart==>"+uri); + player_view.setVisibility(VISIBLE); + img_view.setVisibility(INVISIBLE); + tx_view.setVisibility(INVISIBLE); + if(uri==null){ + return; + } + SAMPLE_VIDEO_URL = uri; + if (SDK_INT <= 23 || player == null) { + initializePlayer(); + if (player_view != null) { + player_view.onResume(); + } + } + + } + + @Override + public void onImageRestart(String uri){ + img_view.setVisibility(VISIBLE); + if(!TextUtils.isEmpty(tx_view.getText())) { + tx_view.setVisibility(VISIBLE); + } + player_view.setVisibility(GONE); + Glide.with(mContext).load(uri).into(img_view); + + } + + + @Override + public void onImageRestartLocal(String path){ + LogUtils.loge("onImageRestartLocal==>"+path); + if(path==null){ + return; + } + img_view.setVisibility(VISIBLE); + if(!TextUtils.isEmpty(tx_view.getText())) { + tx_view.setVisibility(VISIBLE); + } + stopView(); + player_view.setVisibility(INVISIBLE); + File tmpfile= new File(path); + LogUtils.loge("tmpfile===>"+tmpfile.exists()); + if(tmpfile.exists()) { + Glide.with(mContext).load(tmpfile).into(img_view); + } + } + + + private void onStop(){ + + img_view.setVisibility(VISIBLE); + if(!TextUtils.isEmpty(tx_view.getText())) { + tx_view.setVisibility(VISIBLE); + } + player_view.setVisibility(INVISIBLE); + if (SDK_INT > 23) { + if (player_view != null) { + if(player_view.getPlayer()!=null&&player_view.getPlayer().isPlaying()) { + player_view.onPause(); + } + } + releasePlayer(); + } + } + + @Override + public void loadIamgeRes(String uri,int defaultImageId){ + img_view.setVisibility(VISIBLE); + if(!TextUtils.isEmpty(tx_view.getText())) { + tx_view.setVisibility(VISIBLE); + } + player_view.setVisibility(INVISIBLE); + Glide.with(mContext).load(uri).error(defaultImageId).into(img_view); + } + + @Override + public void loadDefaultImage(int resId){ + img_view.setImageResource(resId); + } + + private void releasePlayer() { + + if(player==null){ + return; + } + adsLoader.setPlayer(null); + player_view.setPlayer(null); + player.release(); + player = null; + } + + + @UnstableApi private void initializePlayer() { + + LogUtils.loge("initializePlayer()"); + adsLoader = + new ImaAdsLoader.Builder(/* context= */ mContext) + .setAdEventListener(buildAdEventListener()) + .build(); + // Set up the factory for media sources, passing the ads loader and ad view providers. + DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(mContext); + + MediaSource.Factory mediaSourceFactory = + new DefaultMediaSourceFactory(dataSourceFactory) + .setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, player_view); + + // Create an ExoPlayer and set it as the player for content and ads. + player = new ExoPlayer.Builder(mContext).setMediaSourceFactory(mediaSourceFactory).build(); + player_view.setPlayer(player); + player_view.setControllerAutoShow(false); + player_view.setFocusable(false); + player_view.setControllerHideOnTouch(true); +// adsLoader.setPlayer(player); + + // Create the MediaItem to play, specifying the content URI and ad tag URI. + Uri contentUri = Uri.parse(SAMPLE_VIDEO_URL); + + + + + +// Uri adTagUri = Uri.parse(SAMPLE_VAST_TAG_URL); + MediaItem mediaItem = + new MediaItem.Builder() + .setUri(contentUri) +// .setAdsConfiguration(new MediaItem.AdsConfiguration.Builder(adTagUri).build()) + .build(); + + // Prepare the content and ad to be played with the SimpleExoPlayer. + player.setMediaItem(mediaItem); + player.addListener(listener); + player.prepare(); + + + + // Set PlayWhenReady. If true, content and ads will autoplay. + player.setPlayWhenReady(true); + } + + @Override + protected void onFocusChanged(boolean gainFocus, int direction, @Nullable Rect previouslyFocusedRect) { + super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); + if(gainFocus){ + setBackgroundResource(R.drawable.app_item_border); + setTranslationZ(10); + setElevation(10); + ScaleAnimation anim = new ScaleAnimation(1f, 1.1f, 1f, 1.1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + anim.setZAdjustment(Animation.ZORDER_TOP); + anim.setDuration(animDuration); + anim.setFillAfter(true); + this.startAnimation(anim); + this.bringToFront(); + }else { + setBackgroundResource(R.color.transparent_background); + setTranslationZ(0); + setElevation(0); + ScaleAnimation anim = new ScaleAnimation(1.1f, 1f, 1.1f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + anim.setZAdjustment(Animation.ZORDER_TOP); + anim.setDuration(animDuration); + anim.setFillAfter(true); + this.startAnimation(anim); + } + +// if(gainFocus){ +// ViewCompat.animate(this).scaleX(1.6f).scaleY(1.6f).translationX(1).start(); +// }else { +// ViewCompat.animate(this).scaleX(1.0f).scaleY(1.0f).translationX(0).start(); +// } + + + + } + + + Player.Listener listener = new Player.Listener() { + @Override + public void onPlaybackStateChanged(int playbackState) { + LogUtils.loge("onPlaybackStateChanged1111111===>"+playbackState); + if(playbackState==Player.STATE_ENDED||playbackState==Player.STATE_IDLE){ + resetView(); + }else if(playbackState ==Player.STATE_READY ){ + img_view.setVisibility(INVISIBLE); + tx_view.setVisibility(INVISIBLE); + player_view.setVisibility(VISIBLE); + } + + + if(mMultiViewListener !=null){ + mMultiViewListener.onPlaybackStateChanged(getId(),playbackState); + } + } + + @Override + public void onPlayerError(PlaybackException error) { + Player.Listener.super.onPlayerError(error); + if(mMultiViewListener !=null){ + mMultiViewListener.onPlaybackStateChanged(getId(),0); + } + } + }; + + @Override + public void resetView(){ + img_view.setVisibility(VISIBLE); + if(!TextUtils.isEmpty(tx_view.getText())) { + tx_view.setVisibility(VISIBLE); + } + player_view.setVisibility(INVISIBLE); + onStop(); +// if(player!=null) { +// player.stop(); +// player.release(); +// } + } + + + @Override + public void stopView(){ + if(player!=null&&player.isPlaying()) { + player.stop(); + releasePlayer(); + } + } + + @Override + public void stopAd() { + + } + + @Override + public void releaseView(){ + if(player!=null&&player.isPlaying()) { + player.stop(); + releasePlayer(); + } + } + @Override + public void pauseView(){ + if(player!=null) { + player.pause(); + } + } + + @Override + public boolean onAdViewClick() { + return false; + } + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/LoadingView.java b/app/src/main/java/com/ik/mboxlauncher/view/LoadingView.java new file mode 100644 index 0000000..92a6f54 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/LoadingView.java @@ -0,0 +1,272 @@ +package com.ik.mboxlauncher.view; + +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.SweepGradient; +import android.os.Handler; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.LinearInterpolator; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.util.LogUtils; + + +public class LoadingView extends View { + + + private int mWidth = 0; + private int mHeight = 0; + //文字X坐标 + private float textX = 0f; + //文字Y坐标 + private float textY = 0f; + private String text = "Loading"; + private Rect textRect = new Rect(); + //1文字距离上方的距离 + private float textTopMargin = 40f; + private RectF rectF = new RectF(); + private float radius = 120f; + //大园弧开始角度 + private float mainstartAngle = 180f; + //大圆弧扫过角度(负值表示顺时针) + private float mainArcSweepAngle = -180f; + //小圆弧开始角度 + private float unitStartAngle = 50f; + //小圆弧扫过角度 (负值表示顺时针) + private float unitSweepAngle = -10f; + //小圆弧之间间隔角度 (负值表示顺时针) + private float unitIntervalAngle = -50f; + //大圆弧路径 + private Path mainArcPath = new Path(); + //小圆弧路径 + private Path unitArcPath = null; + + /** + * 圆弧画笔 + */ + private Paint mPaint; + /** + * 矩形画笔 + */ + private Paint rectPaint; + /** + * 文字画笔 + */ + private Paint textPaint; + + //动画当前值 + private float value = 0f; + //小圆点数目 + private int circleNum = 0; + //小圆点的间距 + private float circleEndMargin=10f; + private float circlRadius = 3f; + private ValueAnimator animator = null; + //RGB颜色数组 为渐变准备为数组,起始颜色值和终止颜色值 + private int[] colors = {Color.parseColor("#744DF4"), Color.parseColor("#AA92F8"), Color.parseColor("#AA5AEC"), Color.parseColor("#744DF4")}; + + + public LoadingView(Context context) { + super(context); + initView(); + } + + public LoadingView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + initView(); + } + + public LoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView(); + } + + public LoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + initView(); + } + + + private void initView() { + intPaint(); + initRect(); + mPaint.setShader(new SweepGradient(rectF.centerX(), rectF.centerY(), colors, null)); + initAnimator(); + + } + + + private void intPaint() { + + mPaint = new Paint(); + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setStrokeCap(Paint.Cap.ROUND); + mPaint.setStrokeWidth(50f); + mPaint.setAntiAlias(true); + mPaint.setDither(true); + mPaint.setColor(Color.RED); + + + rectPaint = new Paint(); + rectPaint.setStyle(Paint.Style.STROKE); + rectPaint.setAntiAlias(true); + rectPaint.setDither(true); + rectPaint.setStrokeWidth(4f); + rectPaint.setColor(Color.WHITE); + + textPaint = new Paint(); + textPaint.setStyle(Paint.Style.FILL); + textPaint.setStrokeCap(Paint.Cap.BUTT); + textPaint.setAntiAlias(true); + textPaint.setDither(true); + textPaint.setTextSize(50f); + textPaint.setColor(Color.WHITE); + + } + + private void initRect() { + rectF.left = -radius; + rectF.right = radius; + rectF.top = -radius; + rectF.bottom = radius; + } + + private void initAnimator() { + animator = ValueAnimator.ofFloat(0, 360); + animator.setDuration(4000); + animator.setRepeatCount(ValueAnimator.INFINITE); + animator.setRepeatMode(ValueAnimator.RESTART); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(@NonNull ValueAnimator animation) { + value = (float) animation.getAnimatedValue(); + + mainstartAngle =value; + unitStartAngle = value; + int tmp=(int) (value%3); + if(tmp==0&&value<120){ + circleNum = tmp+1; + } + if(tmp==1&&value<240&&value>120){ + circleNum = tmp+1; + } + + if(tmp==2&&value<360&&value>240){ + circleNum = tmp+1; + } + + invalidate(); + } + }); + animator.setInterpolator(new LinearInterpolator()); + animator.start(); + } + + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + mWidth = w; + mHeight = h; + textPaint.getTextBounds(text, 0, text.length(), textRect); + calculateTextPos(); + + } + + @Override + protected void onDraw(@NonNull Canvas canvas) { + super.onDraw(canvas); + //将画布移动到屏幕中央 + canvas.translate(mWidth / 2f, mHeight / 2f); + //绘制矩形 +// canvas.drawRect(rectF, rectPaint); + //绘制大圆弧 + drawMainArc(canvas); + //绘制两个小圆弧 + drawUnitArc(canvas); + //绘制文本 + drawTextAndLoading(canvas); + } + + + /** + * 绘制主圆弧[step 1- 固定的开始角度] + */ + private void drawMainArc(Canvas canvas) { +// mPaint.setColor(Color.RED); +// mainArcPath.addArc(rectF, mainstartAngle, mainArcSweepAngle); + canvas.drawArc(rectF, mainstartAngle, mainArcSweepAngle, false, mPaint); + } + + /** + * 绘制小圆弧[step 1 - 固定的开始角度] + */ + private void drawUnitArc(Canvas canvas) { + float startAngle01 = -unitStartAngle; + float startAngle02 = startAngle01 + unitIntervalAngle + unitSweepAngle / 2; + float startAngle03 = startAngle02 + unitIntervalAngle + unitSweepAngle / 2; + float startAngle04 = startAngle03 + unitIntervalAngle + unitSweepAngle / 2; + float startAngle05 = startAngle04 + unitIntervalAngle + unitSweepAngle / 2; + float startAngle06 = startAngle05 + unitIntervalAngle + unitSweepAngle / 2; + + canvas.drawArc(rectF, startAngle01, -unitSweepAngle, false, mPaint); + canvas.drawArc(rectF, startAngle02, -unitSweepAngle, false, mPaint); + canvas.drawArc(rectF, startAngle03, -unitSweepAngle, false, mPaint); + canvas.drawArc(rectF, startAngle04, -unitSweepAngle, false, mPaint); + canvas.drawArc(rectF, startAngle05, -unitSweepAngle, false, mPaint); + canvas.drawArc(rectF, startAngle06, -unitSweepAngle, false, mPaint); + +// for (int i = 1; i < 3; i++) { +// unitArcPath = new Path(); +// mPaint.setColor(Color.WHITE); +// //计算小圆弧路径 +//// unitArcPath.addArc(rectF, -unitStartAngle * i + unitIntervalAngle + unitSweepAngle / 2, -unitSweepAngle); +//// //绘制小圆弧路径 +//// canvas.drawPath(unitArcPath, mPaint); +// LogUtils.loge("unitStartAngle:"+i+"|"+(-unitStartAngle * i + unitIntervalAngle + unitSweepAngle / 2)); +// canvas.drawArc(rectF,-unitStartAngle * i + unitIntervalAngle + unitSweepAngle / 2,-unitSweepAngle,false,mPaint); +// } + } + + /** + * 绘制文字 + */ + private void drawTextAndLoading(Canvas canvas) { + canvas.drawText(text, textX, Math.abs(textRect.top) + Math.abs(textRect.bottom) + radius + textTopMargin, textPaint); + + for (int i = 0; i < circleNum; i++) { + float tx = (textX + Math.abs(textRect.right) + circleEndMargin + i * circleEndMargin); + canvas.drawCircle(tx, Math.abs(textRect.top) + Math.abs(textRect.bottom) + radius + textTopMargin, circlRadius, textPaint); + } + + } + + /** + * 计算文字绘制坐标 + */ + private void calculateTextPos() { + textX = -Math.abs(textRect.right - textRect.left) / 2f; + textY = Math.abs(textRect.top) + Math.abs(textRect.bottom); + } + + + + public void destory(){ + if(animator!=null) { + animator.cancel(); + } + } + +} + + + diff --git a/app/src/main/java/com/ik/mboxlauncher/view/MultiView.java b/app/src/main/java/com/ik/mboxlauncher/view/MultiView.java new file mode 100644 index 0000000..0d34bf5 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/MultiView.java @@ -0,0 +1,81 @@ +package com.ik.mboxlauncher.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.FrameLayout; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public abstract class MultiView extends FrameLayout { + + protected MultiViewListener mMultiViewListener; + + + public MultiView(@NonNull Context context) { + super(context); + initView( context,null); + } + + public MultiView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + initView( context,attrs); + } + + public MultiView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView( context,attrs); + } + + public MultiView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + initView( context,attrs); + } + + + public abstract void initView(Context context, AttributeSet attrs); + + public abstract void onVideoRestart(String uri); + + public abstract void onImageRestart(String uri); + + public abstract void onImageRestartLocal(String path); + + public abstract void loadIamgeRes(String uri,int defaultImageId); + + + public abstract void loadDefaultImage(int resId); + + public abstract void resetView(); + + + public abstract void stopView(); + public abstract void stopAd(); + + public abstract void releaseView(); + + public abstract void pauseView(); + + public boolean isAdPlaying(){ + return false; + } + + public abstract boolean onAdViewClick(); + + + public MultiViewListener getMultiViewListener() { + return mMultiViewListener; + } + + public void setMultiViewListener(MultiViewListener mMultiViewListener) { + this.mMultiViewListener = mMultiViewListener; + } + + + + public interface MultiViewListener{ + public void onPlaybackStateChanged(int viewId,int playbackState); + } + + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/MyLinearLayout.java b/app/src/main/java/com/ik/mboxlauncher/view/MyLinearLayout.java new file mode 100644 index 0000000..ae9a466 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/MyLinearLayout.java @@ -0,0 +1,56 @@ +package com.ik.mboxlauncher.view; + +import android.content.Context; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +import com.android.util.GsonUtil; +import com.android.util.LogUtils; + +public class MyLinearLayout extends LinearLayout { + public MyLinearLayout(Context context) { + super(context); + LogUtils.loge("MyLinearLayout:"); + } + + public MyLinearLayout(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + LogUtils.loge("MyLinearLayout:"); + } + + public MyLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + LogUtils.loge("MyLinearLayout:"); + } + + public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + LogUtils.loge("MyLinearLayout:"); + + } + + + @Override + protected void onFocusChanged(boolean gainFocus, int direction, @Nullable Rect previouslyFocusedRect) { + super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); + LogUtils.loge("onFocusChanged:"+gainFocus+"|"+direction+"|"+ GsonUtil.GsonString(previouslyFocusedRect)); + + } + + @Override + protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { + + LogUtils.loge("onRequestFocusInDescendants:"+direction+"|"+ GsonUtil.GsonString(previouslyFocusedRect)); + + + + + + return super.onRequestFocusInDescendants(direction, previouslyFocusedRect); + + + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/MyRelativeLayout.java b/app/src/main/java/com/ik/mboxlauncher/view/MyRelativeLayout.java new file mode 100644 index 0000000..9a1e0ca --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/MyRelativeLayout.java @@ -0,0 +1,450 @@ +/*------------------------------------------------------------------------- + + -------------------------------------------------------------------------*/ +package com.ik.mboxlauncher.view; + +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.drawable.Drawable; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.ImageView; +import android.view.View; +import android.view.ViewGroup; +import android.view.MotionEvent; +import android.view.animation.Animation; +import android.view.animation.ScaleAnimation; +import android.view.animation.Animation.AnimationListener; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.Matrix; +import android.util.AttributeSet; + +import com.ik.mboxlauncher.R; + + +public class MyRelativeLayout extends RelativeLayout { + private final static String TAG = "MyRelativeLayout"; + private ImageView scaleImage; + private Context mContext = null; + private static Rect imgRect; + private float scalePara = 1.1f; + private float shortcutScalePara = 1.1f; + private float framePara = 1.09f; + private int animDuration=70; + private int animDelay = 0; + public static View CurFView=null; + private final int MODE_HOME_RECT = 0; + private final int MODE_HOME_SHORTCUT = 1; + private final int MODE_CHILD_SHORTCUT = 2; +// private JsonUtils jsonUtils; + public MyRelativeLayout(Context context) { + super(context); + } + + public MyRelativeLayout(Context context, AttributeSet attrs) { + super(context, attrs); + mContext = context; + } + + public MyRelativeLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public void onDraw(Canvas canvas) { + // TODO Auto-generated method stub + super.onDraw(canvas); + } + + + @Override + protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { + super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); +// setAddShortcutHead(); +// if (gainFocus == true && !Launcher.isInTouchMode && !Launcher.dontDrawFocus) { +// setNumberOfScreen(); +// if (Launcher.prevFocusedView != null && (isParentSame(this, Launcher.prevFocusedView) +// || Launcher.isShowHomePage)) { +// if (!Launcher.dontRunAnim && !Launcher.IntoCustomActivity) { +// Launcher.layoutScaleShadow.setVisibility(View.INVISIBLE); +// Rect preRect = new Rect(); +// Launcher.prevFocusedView.getGlobalVisibleRect(preRect); +// setShadowEffect(); +// startFrameAnim(preRect); +// } else if (!(Launcher.IntoCustomActivity && Launcher.isShowHomePage && Launcher.ifChangedShortcut)) { +// Launcher.dontRunAnim = false; +// setSurface(); +// } +// } else { +// if (Launcher.isShowHomePage || Launcher.dontRunAnim || Launcher.IntoCustomActivity) { +// Launcher.IntoCustomActivity = false; +// setSurface(); +// } +// } +// } else if (!Launcher.isInTouchMode) { +// Launcher.prevFocusedView = this; +// if (!Launcher.dontRunAnim) { +// ScaleAnimation anim = new ScaleAnimation(1.07f, 1f, 1.07f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); +// anim.setZAdjustment(Animation.ZORDER_TOP); +// anim.setDuration(animDuration); +// anim.setStartTime(animDelay); +// if (!(this.getParent() instanceof MyGridLayout)) { +// this.bringToFront(); +// ((View) this.getParent()).bringToFront(); +// Launcher.viewHomePage.bringToFront(); +// } +// this.startAnimation(anim); +// } +// } + } + +// private void setAddShortcutHead() { +// View parent = (View) this.getParent(); +// if (parent == (View) Launcher.videoShortcutView) { +// Launcher.current_shortcutHead = CustomAppsActivity.VIDEO_SHORTCUT_HEAD; +// } else if (parent == (View) Launcher.recommendShortcutView) { +// Launcher.current_shortcutHead = CustomAppsActivity.RECOMMEND_SHORTCUT_HEAD; +// } else if (parent == (View) Launcher.musicShortcutView) { +// Launcher.current_shortcutHead = CustomAppsActivity.MUSIC_SHORTCUT_HEAD; +// } else if (parent == (View) Launcher.localShortcutView) { +// Launcher.current_shortcutHead = CustomAppsActivity.LOCAL_SHORTCUT_HEAD; +// } else { +// Launcher.current_shortcutHead = CustomAppsActivity.HOME_SHORTCUT_HEAD; +// } +// } + +// private void setNumberOfScreen() { +// if (this.getParent() instanceof MyGridLayout) { +// MyGridLayout parent = (MyGridLayout) this.getParent(); +// if (parent == Launcher.videoShortcutView) { +// Launcher.tx_video_count.setText(Integer.toString(Launcher.videoShortcutView.indexOfChild(this) + 1)); +// } else if (parent == Launcher.recommendShortcutView) { +// Launcher.tx_recommend_count.setText(Integer.toString(Launcher.recommendShortcutView.indexOfChild(this) + 1)); +// } else if (parent == Launcher.appShortcutView) { +// Launcher.tx_app_count.setText(Integer.toString(Launcher.appShortcutView.indexOfChild(this) + 1)); +// } else if (parent == Launcher.musicShortcutView) { +// Launcher.tx_music_count.setText(Integer.toString(Launcher.musicShortcutView.indexOfChild(this) + 1)); +// } else if (parent == Launcher.localShortcutView) { +// Launcher.tx_local_count.setText(Integer.toString(Launcher.localShortcutView.indexOfChild(this) + 1)); +// } +// } +// } + + public class TransAnimationListener implements AnimationListener { + private Animation scaleAnim; + private ViewGroup mView; + + public TransAnimationListener(Context context, ViewGroup view, Animation anim) { + scaleAnim = anim; + mView = view; + } + + @Override + public void onAnimationStart(Animation animation) { + } + + @Override + public void onAnimationEnd(Animation animation) { +// scaleAnim.reset(); +// if (!Launcher.animIsRun) { +// Launcher.layoutScaleShadow.setVisibility(View.VISIBLE); +// //Launcher.frameView.setVisibility(View.VISIBLE); +// } + } + + @Override + public void onAnimationRepeat(Animation animation) { + } + } + + public class ScaleAnimationListener implements AnimationListener { + @Override + public void onAnimationStart(Animation animation) { + } + + @Override + public void onAnimationEnd(Animation animation) { +// if (!Launcher.animIsRun) { +// Launcher.layoutScaleShadow.setVisibility(View.VISIBLE); +// // Launcher.frameView.setVisibility(View.VISIBLE); +// } + } + + @Override + public void onAnimationRepeat(Animation animation) { + } + } + + private void startFrameAnim(Rect preRect) { + imgRect = new Rect(); + this.getGlobalVisibleRect(imgRect); + //setTransFramePosition(preRect); + /*AnimationSet animationSet = new AnimationSet(true); + TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, imgRect.left-preRect.left,0.0f, imgRect.top-preRect.top); + translateAnimation.setDuration(animDuration); + ScaleAnimation scaleAnimation = new ScaleAnimation(1f, (float)(imgRect.right-imgRect.left)/(float)(preRect.right-preRect.left), + 1f, (float)(imgRect.bottom-imgRect.top)/(float)(preRect.bottom-preRect.top)); + // Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f ); + scaleAnimation.setDuration(animDuration); + scaleAnimation.setStartTime(animDelay); + animationSet.addAnimation(scaleAnimation); + animationSet.addAnimation(translateAnimation); + translateAnimation.setAnimationListener(new TransAnimationListener(mContext, this, scaleAnimation)); + */ + + ScaleAnimation shadowAnim = new ScaleAnimation(0.95f, 1f, 0.95f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + shadowAnim.setDuration(animDuration); + shadowAnim.setStartTime(animDelay); + shadowAnim.setAnimationListener(new ScaleAnimationListener()); + +// Launcher.layoutScaleShadow.startAnimation(shadowAnim); + //Launcher.trans_frameView.startAnimation(animationSet); + } + + public void setSurface() { + setShadowEffect(); +// if (!Launcher.animIsRun) { +// //Launcher.frameView.setVisibility(View.VISIBLE); +// Launcher.layoutScaleShadow.setVisibility(View.VISIBLE); +// } + } + + public void setShadowEffect() { + float bgScalePara; + Rect layoutRect; + Bitmap scaleBitmap = null; + Bitmap shadowBitmap; + ViewGroup mView = this; + TextView scaleText; + int screen_mode; + String text = null; +// +// //Launcher.trans_frameView.bringToFront(); +// Launcher.layoutScaleShadow.bringToFront(); +// // Launcher.frameView.bringToFront(); +// +// screen_mode = getScreenMode(mView); +// +// imgRect = new Rect(); +// mView.getGlobalVisibleRect(imgRect); +// //setFramePosition(imgRect); +// +// scaleImage = (ImageView) Launcher.layoutScaleShadow.findViewById(R.id.img_focus_unit); +// scaleText = (TextView) Launcher.layoutScaleShadow.findViewById(R.id.tx_focus_unit); +// +// if (screen_mode == MODE_HOME_SHORTCUT) { +// bgScalePara = shortcutScalePara; +// } else { +// bgScalePara = scalePara; +// } +// +// if (mView.getChildAt(0) instanceof ImageView) { +// ImageView img = (ImageView) (mView.getChildAt(0)); +// img.buildDrawingCache(); +// Bitmap bmp = img.getDrawingCache(); +// if (bmp == null) { +// Launcher.cantGetDrawingCache = true; +// return; +// } else { +// Launcher.cantGetDrawingCache = false; +// } +// scaleBitmap = zoomBitmap(bmp, (int) (imgRect.width() * bgScalePara), (int) (imgRect.height() * bgScalePara)); +// img.destroyDrawingCache(); +// } +// if (mView.getChildAt(1) instanceof TextView) { +// text = ((TextView) mView.getChildAt(1)).getText().toString(); +// } +// +// shadowBitmap = BitmapFactory.decodeResource(mContext.getResources(), getShadow(mView.getChildAt(0), screen_mode)); +// int layout_width = (shadowBitmap.getWidth() - imgRect.width()) / 2; +// int layout_height = (shadowBitmap.getHeight() - imgRect.height()) / 2; +// layoutRect = new Rect(imgRect.left - layout_width, imgRect.top - layout_height, imgRect.right + layout_width, imgRect.bottom + layout_height); +// Launcher.layoutScaleShadow.setBackgroundResource(0); +// initStatus(mView.getChildAt(0),scaleText); +// if (screen_mode == MODE_HOME_RECT) { +// Drawable drawable = getDrawable(mView,mView.getChildAt(0)); +// scaleImage.setImageDrawable(drawable); +// } else { +// scaleImage.setImageBitmap(scaleBitmap); +// } +// +// if (text != null) { +// //setTextWidth(scaleText, scaleBitmap.getWidth()); +// setTextMarginAndSize(scaleText, screen_mode); +// scaleText.setText(text); +// } else { +// scaleText.setText(null); +// } +// +// if (screen_mode != MODE_HOME_RECT) { +// Launcher.layoutScaleShadow.setBackgroundResource(getShadow(mView.getChildAt(0), screen_mode)); +// } +// setViewPosition(Launcher.layoutScaleShadow, layoutRect); +// CurFView = mView; + } + + private void setTextMarginAndSize(TextView text, int screen_mode) { + android.widget.RelativeLayout.LayoutParams para; + para = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + +// text.setTextColor(mContext.getResources().getColor(R.color.btn_text_color)); +// if (screen_mode == MODE_HOME_RECT) { +// if (Launcher.REAL_OUTPUT_MODE.equals("4k2knative")) { +// para.setMargins(200, 170, 0, 0); +// } else if (Launcher.REAL_OUTPUT_MODE.equals("720p")) +// para.setMargins(66, 56, 0, 0); +// else +// para.setMargins(70, 60, 0, 0); // para.setMargins(100, 85, 0, 0); +// text.setLayoutParams(para); +// text.setTextSize(28); +// } else { +// para.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); +// para.addRule(RelativeLayout.CENTER_HORIZONTAL); +// if (Launcher.REAL_OUTPUT_MODE.equals("4k2knative")) { +// para.setMargins(130, 0, 130, 100); +// } else if (Launcher.REAL_OUTPUT_MODE.equals("720p")) +// para.setMargins(44, 0, 44, 34); +// else +// para.setMargins(65, 18, 65, 32); +// text.setLayoutParams(para); +// text.setTextSize(26); +// } + } + + private void setTransFramePosition(Rect rect) { +// android.widget.AbsoluteLayout.LayoutParams lp = new android.widget.AbsoluteLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0); +// int rectWidth = rect.right - rect.left; +// int rectHeight = rect.bottom - rect.top; +// +// lp.width = (int) (rectWidth * framePara); +// lp.height = (int) (rectHeight * framePara); +// lp.x = rect.left + (int) ((rectWidth - lp.width) / 2); +// lp.y = rect.top + (int) ((rectHeight - lp.height) / 2); +// Launcher.trans_frameView.setLayoutParams(lp); + } + + private void setFramePosition(Rect rect) { + android.widget.AbsoluteLayout.LayoutParams lp = new android.widget.AbsoluteLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0); + int rectWidth = rect.right - rect.left; + int rectHeight = rect.bottom - rect.top; + + lp.width = (int) (rectWidth * framePara); + lp.height = (int) (rectHeight * framePara); + lp.x = rect.left + (int) ((rectWidth - lp.width) / 2); + lp.y = rect.top + (int) ((rectHeight - lp.height) / 2); + //Launcher.frameView.setLayoutParams(lp); + } + + private void setViewPosition(View view, Rect rect) { + android.widget.AbsoluteLayout.LayoutParams lp = new android.widget.AbsoluteLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0); + lp.width = rect.width(); + lp.height = rect.height(); + lp.x = rect.left; + lp.y = rect.top; + view.setLayoutParams(lp); + } + + private int getScreenMode(ViewGroup view) { + View img = view.getChildAt(0); + View tx = view.getChildAt(1); + String path = img.getResources().getResourceName(img.getId()); + String vName = path.substring(path.indexOf("/") + 1); + + if (vName.equals("img_recommend") || vName.equals("img_video") || vName.equals("img_setting") + || vName.equals("img_app") || vName.equals("img_music") || vName.equals("img_local")) { + return MODE_HOME_RECT; + } else if (tx != null) { + framePara = 1.06f; + return MODE_CHILD_SHORTCUT; + } else { + return MODE_HOME_SHORTCUT; + } + } + + private boolean isParentSame(View view1, View view2) { + if (((ViewGroup) view1.getParent()).indexOfChild(view2) == -1) { + return false; + } else { + return true; + } + } + +// private Drawable getDrawable(View mv,View img){ +// String path = img.getResources().getResourceName(img.getId()); +// String vName = path.substring(path.indexOf("/")+1); +// SharedPreferences sharedPreferences = mContext.getSharedPreferences("mBox",Context.MODE_PRIVATE); +// if(vName.equals("img_video")){ +// return mContext.getDrawable(R.drawable.focus_video); +// }else if (vName.equals("img_recommend")) { +// return mContext.getDrawable(R.drawable.focus_recommend); +// }else if (vName.equals("img_setting")) { +// return mContext.getDrawable(R.drawable.focus_setting); +// } else if (vName.equals("img_app")) { +// return mContext.getDrawable(R.drawable.focus_app); +// } else if (vName.equals("img_music")) { +// return mContext.getDrawable(R.drawable.focus_music); +// } else if (vName.equals("img_local")) { +//// if (JsonUtils.getInstance().getHomeType() == 0) { +//// return mContext.getDrawable(R.drawable.focus_local); +//// } else { +//// return mContext.getDrawable(R.drawable.focus_wetv); +//// } +// } +// return null; +// } + + +// private int getShadow(View img, int mode){ +// String path = img.getResources().getResourceName(img.getId()); +// String vName = path.substring(path.indexOf("/")+1); +// if (vName.equals("img_recommend")) { +// return R.drawable.focus_recommend; +// } else if(vName.equals("img_video")) { +// return R.drawable.focus_video; +// } else if(vName.equals("img_setting")) { +// return R.drawable.focus_setting; +// } else if(vName.equals("img_app")) { +// return R.drawable.focus_app; +// } else if(vName.equals("img_music")) { +// return R.drawable.focus_music; +// } else if(vName.equals("img_local")) { +// return R.drawable.focus_local; +// } else if (mode == MODE_CHILD_SHORTCUT) { +// return R.drawable.shadow_child_shortcut; +// } else if (mode == MODE_HOME_SHORTCUT) { +// return R.drawable.shadow_shortcut; +// } else { +// return -1; +// } +// } + + + public Bitmap zoomBitmap(Bitmap bitmap, int w, int h) { + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + Matrix matrix = new Matrix(); + float scaleWidht = ((float) w / width); + float scaleHeight = ((float) h / height); + matrix.postScale(scaleWidht, scaleHeight); + Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); + return newbmp; + } + + private void initStatus(View img,TextView scaleText){ +// String path = img.getResources().getResourceName(img.getId()); +// String vName = path.substring(path.indexOf("/")+1); +// if (vName.equals("img_local")) { +// if (jsonUtils.getHomeType() == 0) { +// scaleText.setVisibility(View.VISIBLE); +// }else { +// scaleText.setVisibility(View.GONE); +// } +// }else { +// scaleText.setVisibility(View.VISIBLE); +// } + } + +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/MyScrollView.java b/app/src/main/java/com/ik/mboxlauncher/view/MyScrollView.java new file mode 100644 index 0000000..53ba06a --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/MyScrollView.java @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------- + +-------------------------------------------------------------------------*/ +package com.ik.mboxlauncher.view; + +import android.content.Context; +import android.widget.ScrollView; +import android.view.MotionEvent; +import android.util.AttributeSet; + + +public class MyScrollView extends ScrollView{ + private final static String TAG="MyScrollView"; + private Context mContext; + + public MyScrollView (Context context){ + super(context); + } + + public MyScrollView (Context context, AttributeSet attrs){ + super(context, attrs); + mContext = context; + } + + @Override + public boolean onTouchEvent (MotionEvent event){ + // Log.d(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ touch ="+ this); + return false; + } + + @Override + public boolean onGenericMotionEvent(MotionEvent event) { +// Launcher.layoutScaleShadow.setVisibility(View.INVISIBLE); + //Launcher.frameView.setVisibility(View.INVISIBLE); + return super.onGenericMotionEvent(event); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/MyTextView.java b/app/src/main/java/com/ik/mboxlauncher/view/MyTextView.java new file mode 100644 index 0000000..c256056 --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/MyTextView.java @@ -0,0 +1,25 @@ +package com.ik.mboxlauncher.view; + +import android.content.Context; +import android.widget.TextView; +import android.util.AttributeSet; + + +public class MyTextView extends TextView { + public MyTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public MyTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public MyTextView(Context context) { + super(context); + } + + @Override + public boolean isFocused() { + return true; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ik/mboxlauncher/view/SplashView.java b/app/src/main/java/com/ik/mboxlauncher/view/SplashView.java new file mode 100644 index 0000000..78264cf --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/SplashView.java @@ -0,0 +1,275 @@ +package com.ik.mboxlauncher.view; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.RelativeLayout; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.media3.common.Player; + +import com.android.database.lib.AdsInfoBean; +import com.android.monitor.DataBeeObserver; +import com.android.monitor.impl.EventFactory; +import com.android.nebulasdk.ADManager; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.io.File; + +public class SplashView { + + + private View mView; + private CountdownTimeTextView txt_time; + private RelativeLayout container; + private Drawable bgDrawable=null; + private long crete_time=0; + private static String AD_FILE_PATH=null; + private HomeMultiView ad_splash_view; + private Context mContext; + + private LoadingView loading_view; + private WindowManager windowManager=null; + private WindowManager.LayoutParams params; + private AdsInfoBean adsInfoBeanInfo=null; + private Handler mHandler= new Handler(){ + @Override + public void handleMessage(@NonNull Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 0: + if(adsInfoBeanInfo!=null) { + if (ADManager.ADTYPE_VIDEO.equals(adsInfoBeanInfo.getAdType())) { +// loading_view.setVisibility(View.VISIBLE); + LogUtils.loge("loading ADTYPE_VIDEO"); + ad_splash_view.onVideoRestart(adsInfoBeanInfo.getLocalFilePath()); + } else if (ADManager.ADTYPE_IMAGE.equals(adsInfoBeanInfo.getAdType())) { +// loading_view.setVisibility(View.GONE); + LogUtils.loge("loading ADTYPE_IMAGE"); + ad_splash_view.onImageRestartLocal(adsInfoBeanInfo.getLocalFilePath()); + } + } + mHandler.sendEmptyMessageDelayed(1,1000); + break; + case 1: + txt_time.starTimeUi(new CountdownTimeTextView.TextUiCallBack() { + @Override + public void onEndCallback() { + txt_time.setVisibility(View.INVISIBLE); + mHandler.sendEmptyMessageDelayed(2,1000); + } + + }); + + break; + case 2: + dismiss(); + ad_splash_view.stopView(); + if(mSplashAdListener!=null){ + mSplashAdListener.onEnd(); + } + break; + } + } + }; + public SplashView(@NonNull Context context) { + mContext = context; + // 设置布局参数 + params = new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT, + Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : + WindowManager.LayoutParams.TYPE_PHONE, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSLUCENT); + + params.gravity = Gravity.TOP | Gravity.START; + params.x = 0; + params.y = 100; + // 获取WindowManager并添加视图 + windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); + initView(context); + adsInfoBeanInfo= ADManager.getInstance().getADInfoById(100); + } + + private void initView(Context context){ + + mView = LayoutInflater.from(context).inflate(R.layout.activity_splash_screen,null); + txt_time= mView.findViewById(R.id.txt_time); + loading_view =mView.findViewById(R.id.loading_view); + container = mView.findViewById(R.id.container); + ad_splash_view = mView.findViewById(R.id.ad_splash_view); +// ad_splash_view.setMultiViewListener(new HomeMultiView.MultiViewListener() { +// @Override +// public void onPlaybackStateChanged(int viewId, int playbackState) { +// +// if(playbackState== Player.STATE_ENDED||playbackState==Player.STATE_IDLE){ +// //退出' +// DataBeeObserver.getInstance().recordEventMsg( +// EventFactory.EVENT_GOOGLE_AD, +// 100, +// System.currentTimeMillis(), +// System.currentTimeMillis(), +// "AdCompleted" +// ); +// dismiss(); +// } +// } +// }); + } + + + + + public void show(){ + + + if (windowManager != null && mView != null) { + try { + windowManager.addView(mView, params); + } catch (Exception e) { + e.printStackTrace(); + } + } + AdsInfoBean adsInfoBeanInfo= ADManager.getInstance().getADInfoById(100); + + if(adsInfoBeanInfo==null){ + LogUtils.loge("adsInfoBeanInfo is null===>"); + mHandler.sendEmptyMessageDelayed(2,10000); + return ; + } + + if(adsInfoBeanInfo.getLocalFilePath()==null){ + LogUtils.loge("getLocalFilePath is null===>"); + mHandler.sendEmptyMessageDelayed(2,10000); + return ; + } + File file = new File(adsInfoBeanInfo.getLocalFilePath()); + if(!file.exists()){ + LogUtils.loge("file is not exits===>"); + mHandler.sendEmptyMessageDelayed(2,10000); + return ; + } + + + if(adsInfoBeanInfo.getState()==0){ + LogUtils.loge("splash task is closd "); + mHandler.sendEmptyMessageDelayed(2,5000); + return ; + } + + + + mHandler.sendEmptyMessageDelayed(0,300); + + + +// if(loadSplashAd()){ +// // 确保windowManager和floatingView不为null +// if (windowManager != null && mView != null) { +// try { +// windowManager.addView(mView, params); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// }; + } + + public void dismiss(){ + if (mView != null && windowManager != null) { + try { + if (mView.isAttachedToWindow()) { + windowManager.removeView(mView); + } + } catch (IllegalArgumentException e) { + // 视图可能已经被移除 + e.printStackTrace(); + } + } + } + + + + +// private boolean loadSplashAd(){ +// AdsInfoBean adsInfoBeanInfo= ADManager.getInstance().getADInfoById(100); +// +// if(adsInfoBeanInfo==null){ +// LogUtils.loge("adsInfoBeanInfo is null===>"); +// return false; +// } +// +// if(adsInfoBeanInfo.getLocalFilePath()==null){ +// LogUtils.loge("getLocalFilePath is null===>"); +// return false; +// } +// File file = new File(adsInfoBeanInfo.getLocalFilePath()); +// if(!file.exists()){ +// LogUtils.loge("file is not exits===>"); +// return false; +// } +// +// +// if(adsInfoBeanInfo.getState()==0){ +// LogUtils.loge("splash task is closd "); +// return false; +// } +// +// if(ADManager.ADTYPE_VIDEO.equals(adsInfoBeanInfo.getAdType())) { +//// loading_view.setVisibility(View.VISIBLE); +// LogUtils.loge("loading ADTYPE_VIDEO"); +// ad_splash_view.onVideoRestart(adsInfoBeanInfo.getLocalFilePath()); +// }else if(ADManager.ADTYPE_IMAGE.equals(adsInfoBeanInfo.getAdType())) { +//// loading_view.setVisibility(View.GONE); +// LogUtils.loge("loading ADTYPE_IMAGE"); +// ad_splash_view.onImageRestartLocal(adsInfoBeanInfo.getLocalFilePath()); +// } +// +// +// +// mHandler.postDelayed(new Runnable() { +// @Override +// public void run() { +// txt_time.starTimeUi(new CountdownTimeTextView.TextUiCallBack() { +// @Override +// public void onEndCallback() { +// txt_time.setVisibility(View.INVISIBLE); +// ad_splash_view.stopView(); +// dismiss(); +// +// } +// }); +// } +// },1000*5); +// +// return true; +// } + + + private SplashAdListener mSplashAdListener; + + public SplashAdListener getmSplashAdListener() { + return mSplashAdListener; + } + + public void setmSplashAdListener(SplashAdListener mSplashAdListener) { + this.mSplashAdListener = mSplashAdListener; + } + + public interface SplashAdListener{ + public void onEnd(); + } +} diff --git a/app/src/main/java/com/ik/mboxlauncher/view/TimeTextView.java b/app/src/main/java/com/ik/mboxlauncher/view/TimeTextView.java new file mode 100644 index 0000000..d5eb49c --- /dev/null +++ b/app/src/main/java/com/ik/mboxlauncher/view/TimeTextView.java @@ -0,0 +1,99 @@ +package com.ik.mboxlauncher.view; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Handler; +import android.text.format.DateFormat; +import android.util.AttributeSet; +import android.widget.TextView; + +import com.android.util.DateUtil; +import com.android.util.LogUtils; +import com.ik.mboxlauncher.R; + +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + + +//时间的textView +@SuppressLint("AppCompatCustomView") +public class TimeTextView extends TextView { + + /*对应的时间格式为:时间 星期,月 日*/ + private static final int FORMAT01=0x00; + private int DATE_FORMAT=FORMAT01; + + private Handler handler = new Handler(); + + public TimeTextView(Context context) { + super(context); + } + + public TimeTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public TimeTextView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + public TimeTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public void starTimeUi(){ + handler.post(timeRunnable); + } + + public void cancelTimeUi(){ + handler.removeCallbacks(timeRunnable); + } + + + Runnable timeRunnable = new Runnable() { + @Override + public void run() { + String timeStr= formatTimeDynamic(getContext()); +// String weekStr = DateUtil.getNowWeek(); + String dateStr = getDate(); + setText(timeStr+" "+dateStr); + handler.postDelayed(this,500); + } + }; + + + public static boolean is24HourFormat(Context context) { + // 直接使用系统提供的API判断 + return android.text.format.DateFormat.is24HourFormat(context); + } + + + + public static String formatTimeDynamic(Context context) { + String formatPattern; + // 判断设备是否使用 24 小时制 + if (DateFormat.is24HourFormat(context)) { + formatPattern = "HH:mm "; // 24 小时制Log + } else { + formatPattern = "h:mm a"; // 12 小时制(如 "2:30 PM") + } + return DateFormat.format(formatPattern, new Date()).toString(); + } + + private String getDate(){ + final Calendar c = Calendar.getInstance(); + int int_Month = c.get(Calendar.MONTH); + String mDay = Integer.toString(c.get(Calendar.DAY_OF_MONTH)); + int int_Week = c.get(Calendar.DAY_OF_WEEK) -1; + String str_week = this.getResources().getStringArray(R.array.week)[int_Week]; + String mMonth = this.getResources().getStringArray(R.array.month)[int_Month]; + String date; + if (Locale.getDefault().getLanguage().equals("zh")) { + date = str_week + " , " + mMonth + " " + mDay + this.getResources().getString(R.string.str_day); + }else { + date = str_week + " , " + mMonth + " " + mDay; + } + return date; + } + +} diff --git a/app/src/main/res/anim/anim_alpha_show.xml b/app/src/main/res/anim/anim_alpha_show.xml new file mode 100644 index 0000000..2b05b23 --- /dev/null +++ b/app/src/main/res/anim/anim_alpha_show.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..a07c69fa5a0f4da5d5efe96eea12a543154dbab6 GIT binary patch literal 2574 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 Z^D&yVMM1yl#~)V;;4fR^DvUj1{so>5cYy!^ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/app_border.xml b/app/src/main/res/drawable/app_border.xml new file mode 100644 index 0000000..b3bb2e9 --- /dev/null +++ b/app/src/main/res/drawable/app_border.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable/app_info_bg.xml b/app/src/main/res/drawable/app_info_bg.xml new file mode 100644 index 0000000..db92bf0 --- /dev/null +++ b/app/src/main/res/drawable/app_info_bg.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/app_info_border.xml b/app/src/main/res/drawable/app_info_border.xml new file mode 100644 index 0000000..c99d927 --- /dev/null +++ b/app/src/main/res/drawable/app_info_border.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable/app_item_bg.xml b/app/src/main/res/drawable/app_item_bg.xml new file mode 100644 index 0000000..561596c --- /dev/null +++ b/app/src/main/res/drawable/app_item_bg.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/app_item_border.xml b/app/src/main/res/drawable/app_item_border.xml new file mode 100644 index 0000000..c30c552 --- /dev/null +++ b/app/src/main/res/drawable/app_item_border.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable/app_item_select.xml b/app/src/main/res/drawable/app_item_select.xml new file mode 100644 index 0000000..1d23cd6 --- /dev/null +++ b/app/src/main/res/drawable/app_item_select.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/bg.webp b/app/src/main/res/drawable/bg.webp new file mode 100644 index 0000000000000000000000000000000000000000..da1f4dfe3d5c99cbc110d05a51b3e71517b811a7 GIT binary patch literal 3780 zcmWIYbaUIo$G{No>J$(bV4<)9$PU=WIG0hYf!%_|ZlcFRU)3ebN(vkd8-zGB^B$Hb zN;`1AVZNU;r+wc|Oa9tTMRLDWp4fgnd7}F5d$ze1bjFt|g srQ&F9Fj`5DHV#G`MWb!S(KhmE-(WzyOuP>m{{6p_|KD2fI>Rsm0PR==djJ3c literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/frag_bg.webp b/app/src/main/res/drawable/frag_bg.webp new file mode 100644 index 0000000000000000000000000000000000000000..e94ed4afd523767057e23fe1e1ae1fe802dbab20 GIT binary patch literal 10060 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 C2Oweq literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/img_filemanager.webp b/app/src/main/res/drawable/img_filemanager.webp new file mode 100644 index 0000000000000000000000000000000000000000..244c1e6e2954766a5082d2e6d7c43fb3133ecca6 GIT binary patch literal 3278 zcmV;<3^DUkNk&G-3;+OEMM6+kP&gpE3;+PINC2GyDl7r|06vjKolGU8qM{GeeKUTR6{a;+X*Qh`YvOxn#qTrT@~g-%YXF$wEDaCDdr3MztXeJH|;m=7rM{< zKUe?fKgj+n{DOZh{{87+?2G6h<){0>@TdKY{+I5@wuY&lM*buRUTM#UbBexu;WLVI zM#6GN!g5B!Z+~Mb`v55W04VzZzs32}0c?O|h*eY@Z0*oYJK>xa;mzg>lwc

o4?P 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/img_hbomax.webp b/app/src/main/res/drawable/img_hbomax.webp new file mode 100644 index 0000000000000000000000000000000000000000..4902c5570b8c2cfcb167179dacf3c19a42754dd6 GIT binary patch literal 1828 zcmV+<2iy2kNk&E-2LJ$9MM6+kP&gnE2LJ#tC;*)SD#!q*06vjOpi3pBqamX>2|%zC z31e>IbfAlc1F=)HX9n~Aoat@iJ<{{cN9*70m%6`@2e1e9pYR=Set;fae#-yjKji+i zds1qsd5f^lfX{16&XqhS?Sdpei?J%I9cR1VWfgNQdf(RNnymcB5iq_TX+ib4rc3vG4Hb z7q?~`CnJQi3ize>mgo*|8u*CN$bniFk-5##jFQdh^oGeMT zaJ1c62ox)lXxR>SWNbtRg@rOg{X=&1GY%CdVi#Te(%89Q$dpdrMeA;K?0~bu8zE^e zLAy>bU<^!LvS!8DtZdDm^{&0zAyoIAxbNH6fAoOT$AK%FG|h zm-st}k(54s#?s>4Od@{bOf+&;jAC;s#KRP8B>X12n7>_z-#SD}-6B{ZS8T?T0>Ats zL1c*xMvSU#F6l&XG9F4i%qmvx<%ZomT7m4*u zi!Z+w9_6RY;arIkEpu6x;K5T*{mkY&<;Yk7{W|+=|sc_$K-*1;j~A;ME#7U=Cgpq-_gA1 zW`*Z>%)jjP=A=%BE8HwXOct^Rh5EFdSf`o2UtBgZ`dQnD#;V2QPdJEEG0*QVP=~I* zeT~ihs7hv!(NtA8Y_Lal#eR(rM%sw>9H7nh?SFSb$B`wG$!ZmP8nT@4_t&8>`=v(( zO|}OB&v`eVte?qZjM4LffHmJvaHLq{u;~;Vt|>LjJLIF=8>^9lXU^+YMXVchI{PU{ zmhA?d3gv-lVI!o#Fe zS{-1!CjGEcBXl`!i{O*I@-anixP(uKyUi`d=fhL4ZAoicRm&8l+4l&;aSt9Aa7KtyhLzfNWEA2Orp z-b!jIpm7lDSBwN5e;&06_+$Pl?Nka+z-ujPT)8fu3}JOmriI&aLY6IF)1W(x)ieRq z8NJ4*#=q>Ejx!~Z6;`(Rq=Ah24Qx2 zbRE_OTjAXi@uh3DIlLl~iY4N>_L|_6;U?^Yigdi|8g@p`HH7A3_M1BQEMMM~J=n+Q zP8xX*x67mD+?@>-#c3ITfQJ&P)t|1)g~1)U{(aZ?=z!TaK?v1n{EAYK)?0CHfbXNl zn~M$S{`oW{@6NQ6OiZHX9Gvt}#WRV89cWKkvHoACAaU2OS)VtlnbZNP9sGs3`Fil%@MfF&J)_L9Uqj28&J{thB-X@CHLM3`P!% zyr&R;vs+K5K+qMyfWjf+pEpA%ennTO?!gqdG?P(D`yl{SWGG~Xn>(kjU{U@O9=phW SF0P|WIK+lL_W_bDAOHXg@vYGS literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/img_miracastreceive.webp b/app/src/main/res/drawable/img_miracastreceive.webp new file mode 100644 index 0000000000000000000000000000000000000000..f08c780aa781bc45c658843efe24118c311275af GIT binary patch literal 5084 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/img_music.webp b/app/src/main/res/drawable/img_music.webp new file mode 100644 index 0000000000000000000000000000000000000000..428772cbe2262b3ba02e25e24b7bb36af1112c60 GIT binary patch literal 4606 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 Cm+4ag literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/img_netflix.webp b/app/src/main/res/drawable/img_netflix.webp new file mode 100644 index 0000000000000000000000000000000000000000..3b9f68011b051970bf631c45be00e8701659a64a GIT binary patch literal 2168 zcmV-;2#5DlNk&F+2mkVV044X1bY5gw!2t(&&#iBn)mn*#U8`EKk8pJ?m+*E_iOMg)gPEY_wVbTy*&$V`eN@kitFkyXFaQSy*1E{58vDTy z!E}l3TIwZ1iY`O&$iFUZD6=gW)?IpZlH2#jX|dq>EUl2cDo!0i+sd3AdCVA}JkmNP z#U%g~FrK?_T`=eZUeFFA>+uSButC%T$>C&PLc|&p0A&9c-U`vYLI3U5JCC>BzZ1^x z2WWz&M1jyg2Q+{kl$qYJt!I~;RfNj2V>Tgy1F)O}V`>ors{ufvi*8CoTnFvY6UI~6 zSGknRu){V|Nqg2`5Itlj=Y&0;*sEj$#kxf5$PNWV{xqrR9y&G1QDtt8auiuxqg;g+ zR_NCuMU}cW$Wdi(jdB!OTcccs7FNUn0RH{C`{o+t7p#Bwj6YF_>M-SmU~n9GfB*mh zjjM?wmKG?xOcQ^&&`!BC^UAW1{Ryxxr_5*p(01xMaUv7Y(QZ99Ec$&ZH%33d`w$+i zxx@{p?C|2eWW*J7+?5m&M-;n-mtC(G7q0KM+xHC8Y4~hKfPti94q6Zp#xk&DLrq|_ zi(&Nr#*4o73sJ$gX}g5*^39686SOWo)If7(QqNXow><&Ej3yf4Mzg39PvKsEfRQ*} za9DuC^G$)db33MbB^B>**+%roY+wo@v*PptIW0s%SJ)1KfpX$RC!wN4z~$kirW~@+ zutzS$80!#2Ot=<;TrIuoktZb)Gg#0Fb6aNu2r=9L7==PHW61jAXnV>gaMp%y@e59w zZpO{eLN!jsRB5s8)MY*E6qM@NE_pqjP+KOhzUoarjaqE4 zl&V3r1L!*)*38~_k^yNoGwW7}`Hq4X)%l06y?>rF><|H?l006IVW`Lk^I2D`r0GYh zZexY#3;+d*M%8oi)u?!mB+Uw5yAs9wBSO3}&O=SOx{R&mwfPsZeKd7J{djW1BLj6C zqt`#UNt189V&yC(lV4w~?>dua3BfMt>*AZ-Z?j)0~v8uOS zZ!iiKxGvS_b+)XeTIsR3s#UR#{uBr>X!9<0Yy^Ej{HfZsYM>AiN(e3TOkVj+zm_TJ zXH>5$n%{4&ofJYT_nv`6mu%xnRB=U(D3!i{U0no2uP7)3jallv2=7qCz^MszISn@b zsyUU3g6DqL6aur0Wu$82<#YRm)TkIMN4w$6d3tm>Q9gBB&DG;sAR9S-vx4wS2X0S1 zQq)7BcTRa_`T8m6#T&!`FE1MW@cko~4v8mP9ZY56(eki-l9-n>)m%|Ex`AJ|H&JLk zCauk``3u>3(ig{}A-`9w_W-OB)-e-6mX#~!cq3U{QP=5*W*TcOcce8~lFenaft0UGEYcBA(<2-eaRDz6W9UM(wwYlF54eMTmXUpcJ1|S2 zcwa>7xPX}!6P($eGZA!Ao#y6Cxra^}Aa3b05fPe7z;-wol&6+s1tm2ObMVyYQ0BY3 znRdu&t|>7gQuRXls_fyV^^@(W{XMrIu5YZ#$QO}Y2q3}+;;)&F z@r&{MLK_P#L<6ax09^=5!$T#EA`9G_S3vMihhI`qC5i+9UiMv0KfNAERV?D2LZFJS z;d%#mJ(dchyV-Kqdz@$nwaq-=|9Ha@vKl^N2h@>@bU=)lyz&5lCuFubb?I%y z!zXO^{a4iQoWI%e3xXh&WI}wRqzJ{;V;x-cQNX%@4Fh?~1W}$uB zWRLLR6d<P^7?_GSP zl+zvtRF7bQhtF|~p0~k9m5Y*E`fzbybU*0G(Q_VIti#iP3mqh=G8)VY$^Pi}%c!FO ug~o(sM_B-(?tMkdR*|b8%A?-T;Ujdx|L6w+rJjfY00000000000002TdL(B6 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/img_primevideo.webp b/app/src/main/res/drawable/img_primevideo.webp new file mode 100644 index 0000000000000000000000000000000000000000..bb198526c8bd14dd39a2d4f860ed4148a0080327 GIT binary patch literal 2720 zcmV;R3Sae7Nk&GP3IG6CMM6+kP&gor3IG7GJpi2nDl7r|06vjOpiCvCBO)U5=%BC? z31e>je3^0R$(Z}UYiH~5-<4mD-!t|1?O)NjDQiD0&RYMg=mY)F^g;^l>C5x zp?Y znJI)!B>zBy3l+nMfJk1|#kp;Xp9<}x+MNQ>K5Zm0Y`sTQh%6R3=@UouLbK{ll(;}4 zn-F@%tO0Of9s4_Hpu&CMOG5w8HoqnZ0|Pc&{_Kb{)=G2Wd~Kfb%Gd_W*V}7M1h_+2 z8PT)kH2p!?0nGH`Jfcos;WhV*cGk}3M%eSBXAhS$Nz-l>CfhO#<0&}1x{)Ge3r5NS zq`+-O`BhjV|6|mNd~MrM-mk1|E3Y^;R1Ju4jQ=47DdY8y5b8EN{Quzf=ZFd3c zUm&T?uHZdOZ~*@Dum4)+)fV^nfdA{Q-5T;f+d7tx?FP$W000025lJJ8F45TSUuKw? z2o$C_RoHZ#6OpSa=aU0F(<{mrT%tnTpkY^6aiNe|URK~Dj)x0ZsySbKFU9ZP8D#w} z+S{wvFh!0xR#VI|j9a`l&Ff+yM2t^22kYD?@0k41v=?u&d=vVXy$**$^Z3%?NfO=z zmM{hj6yO%^KY5OriQ3|L!}$XKHbxZQ%x>#fQoh+TlmcQbKGeMuV7YKmj9UsRPcMbf zK*DEf!ZRqU7JOC^14}vG#)!G%=Q!=lwca;aD%%cHSnAALNpCEg^#)2bM4Z{yp#wQ3 z{jLSaaryZmXDoty=2??bR{5I1Ofp?zhaI!q=@(;uRo z#BF(PdSlAd9Oz8%*O`W(V^BJ;8S-iVTvLZ=cD(rpG6~06k->%OLeI}5uvc_Rf{ijj z8WXwNQJ;-$@}S#chJvRXm=16q3Tcm@iZ-CM%vgKV~e?|m%fP8GcM>n-UG%PgBuQxg#eDZzdA}KkLR}Vj^U;(H}L>>=8`Jk{JCE3ULEr zC)a)cMdJ-V1$Q;#1dE_Qc{L$QF9h^!{*tnbXi%!&@+j$o&h5r>r_mK|;0d3F(#dwl zNf~)1P!3GEdP@AtBG<;u(?CQwUiI|BZy~y@R{t{)QWQTNV2m}Bpcg2MB?PxQD2Z<`Vc`h z8C(~?@?~Ia8u@ex zJyjEX*Yn#A`?!1BBGsox3xg-W z{voI7?!trI%E9>F@6IB;r1_8~SV=Dt$EC6VQd^EBF_*guGs}Rs?ZK0tn4@Tn(*sTg zo=KWr1_AG2KDT1o8Y*7l1*Zx?4UqoMPQ-WeignRIA57vZ)UOobA)pIDG%ACTgHcc2&!iIqD2KIEWT*=3ze>>eM!61-;2*M1~Y3% z9~BY3B!Q4mAbe5KWarcMAWQ@E-55#yC|`Q-2K~1vDPK99NqPJFisj@L^REf==}qND z?}P5U4{mK1LM8A-tz6^TK{4^WSR;7EE@PW2Gz@v#6rolg^W~UD^H*V%bM>3Vm@j~+ zdE|kwA#LmdB29>{dPwp?4i0o3;ssXBWF+KNeH9_x0YITCADOJpu4K=%t+udn*>$9= z9>1#<-EZlHVaFII+P7o22<7(@gp1C*QASgFY)bsSN{@rv|qC-|E?QS)ba9uLW-8xUa#qe z55PI?bv`=8bE;$_?%Ye$V5|3Z%x(RD+A}jz2aaf-P+b<}Cki1>rm17mahH%+OvHS5KL+WH6hm|vC^3sPv+eqWO8%`Df`WIX{fJ5&y6Nty zlbnv%1C}5TN664_?H^N;-7FF;(P2+2nuNqCT0b1l8UHG##NR`Gmp9c$Y)SnSI9H7W zpEN~s{V*-0o1gMk_C8Z;a)K8^7afrctpE6mwrul5QX?r9aP#agSNJ4Wmp&eLIy~0s zot>@-O>h-2>3{igQ)y8HGbk3|{FIM;p3L`8y4|pH=cDNzH&fuB(Oq++NTiCr$(E}C z_Q=Vme)?G+jJw1QGoUC1@RQAb{Qgq0zZk%Q(=w{d)|U&#d4@77MRdslAWd9Y26F?N a13lv}mDafduUwo4DL?=K000000001EnKMoR literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/img_recommend.webp b/app/src/main/res/drawable/img_recommend.webp new file mode 100644 index 0000000000000000000000000000000000000000..c90a3832000e08a8394c59e2d034fcd1b73388b0 GIT binary patch literal 7940 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

-`+JC#^!)!)ggbh)@fs$W*MhTHAb?UU8hBzf0dQq@2PUfm{Bmef$@iD61!X^W&Pg@@Iy<< z{YjKzVVQkD%4FAy3)<<4;(4qluDk7=)G`Qr0E)?i=MY!wJHHK>vf zd`y{hCEPtQ^Hwn12_v_`@*b(>f_hCiYs;k3fhEj7kDWJexXb4_(2r~dygmaSU(cwV ztmI$mAXxKPY-+IFbvSaXvaDwN(m=kJa@&%+cS&e2YJ6J)_Gj(JqF_p3Cs_vHYw=t- z8)5|BZ{HGuq{>bPfr$dXN@$-5aP*jK#Mk$97)#)Ye#P7HyONTBfQ$0(j?&VwNCpB0 z7MxfG^V?$&T>{%BQ1u3w?srwP8q_yD`bC_jQG@_kZw~y?0TNGeQQSz+Twc}^Sass1jMg!=QA-V=7s(F+d0Dnn(kj38gVfn`G@IkDk}o+I zFl+vE(M(%g_V^dz^50$LBkF4cjrlxx%jPt>)FJ=-*!J!aYt5d9uYZDE6#KSdT*)NR z1BwgAF#ufBk;W{cbn;JZl26#$pfL2@bbnHsrn`n8-_fnf4*uSy5y�wSV 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/img_setting.webp b/app/src/main/res/drawable/img_setting.webp new file mode 100644 index 0000000000000000000000000000000000000000..934c9dbff8ef0a7f4c05ebce4445985c85d4791a GIT binary patch literal 2630 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/img_status_ethernet.png b/app/src/main/res/drawable/img_status_ethernet.png new file mode 100644 index 0000000000000000000000000000000000000000..d59e5ba146bd434530f4720e326b375583224b7c GIT binary patch literal 924 zcmV;N17rM&P)Px&R!KxbRCr$PTH8xhK^*>m>^?+77Ib?J>>*H43^KZEy<}w;35kUTQKm+jgr-6F zKJs7`sR+6*JIl8lRW_R5)^Po%wM7K!*{Y3QGDX>-m zm^ll;2LOu`U3pZzRw6oPmxFEq?f^L0{;&h@d;1cOfzRhdQ*#}bE?XjEuOy<;=p=Ll z&<$X7;l>gS504}q01@!|%@*t{-y{CrK}0XT3_vLnJvRVEA&?Xa+-kjsjEwnOB++*N z3EsRG%A0By38W4KM!ydrGjo9!0GgXF<96#k1At+GssxyM9)NQI3KY1S3t-{UU;x43 z?`bz{3i9Fi`xV?eo4O_eW)836TC&vW)D-}jS&ZCZATWaJs``l0)0q3TYroHrZN*!0 z;Zmb?IJW@U1)%d$dk2o!G)O1mhCz1rDs;c?l6GYPaAO%{X2SqG2~->?!>RgeX=FW|Ha zBx4RR02l_uF9C7r(%IF9+`Js2h_yuYFPx&0!c(cRCr$PS}|)CK@k2vu&}T&V4+~4U}52pFoh_n7*Q~Vf`WpDU<3sPK^qZK zFk)k`jg<)~3L>VkS22a1DJ(2fyuu=dFy0sD!tp%K9^U5Va z19%T$4}eWg4f+rHU&WfwNSeU-|zrboYzrzpbYye?=~z2D$einu>Vn)aLnu=fH$ehs71MaNzlwx*ogDm zd2znhd8fc*0GC>HELBxj0B!-81aPKsZt*V`sSG{=;N}`vf~7fG0eA>tDs?MHBo_c= zD}>A}A|QbRN{niP1~n8o4`83qUk9)RplqBpt#{N!X-H1;8Z!Xq{JGSjccnu^Nx4k8 zBd352eCLkIxOtLlRaGAA1etK7$4Cy$OvmXrpIacg+hvcr!bO!)Y3Ff*JOgsfr!ZfE$P#`D}6v*_wK;(e953u`1({eRu3U5Jo zzV8Oj>@Wb;=<9i`G)pN)HtGeu1H0@uG5Q_AdK$W=Rt<2ciBXLKXrjCevH?IBb}6Tg z5dk^T?Sk%zfG+G(P8%Zva-!P>-4Ov@*rl8{Mg-(Uw+p%>0=lqEIc@BH1pEd!_e4+$ S7q`Fw0000Px&&PhZ;RCr$PnNNsMQ546&rz|XHK~WZ?C<|r7N*0nLib5=Al7);KnT4{Dq)d@n zC>9DCH4|kDp%gNOG7BqfQIuII78Vv3>UiJjyt?y#@4xrvJ>I>mY2JPJ-t#%%^XI;w zpyNY2Za+K#uYisd@FCD~0r({7L%@eX#|iil=(qrU74RY8L!jdXN`-)`o&hkF!0tDI zOCoaPUtn7nzy|vlnsF_1ti({3&7qs zL8uGBM*vqN6m|!y*ao0g5b6TZlLS?DF@T2vcD4yZSpZp8U|K}BN8_MQ2)6b{t4=J% zvjAp9go;ZXxdEtZzld;AsOk;?11al{2LNW`p2t8K5Ru1a6Qiwn(fX3U$T~lQYBd31 zR7Ci9&&UNpRo4P|Dk7`P9@Kp=0)gHlga<{}R#lebml-9Q%YJ6)iOBot9+?2l+xLU+ zu1`cV=jS!zZy~7a5&-XV7#|*q5H^P@4*!{IkgA>pFa}@|U#Jp*g%T6vU6w`wg_NMG zH&fd2BtJ|ADj0Mh#sVaZ*qkS2-j6r!X<TKRhR|P!) zRF#S3o|UWU+Di*=mUlWK+;;Xn0bnxaY;j0EaA3{7nc9yE!H)2{I;`1V`#lf=QNJ z`F#{rAyx_+zc1|SRCO7EFZQfxc%>&nceT39U>W0`>TxYvrE-v%5Rt=~WiSF^7l5g% z8=(~ADR1uAsW^2$E18UQ^>Bg%{gH=c*A8o)toT#5o{#P~V@ z@W&ER&FrfH O0000Ntf{QNeiSWD1M^XI7ok^Pl>i*SoZvG10b( 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/item_add_img.png b/app/src/main/res/drawable/item_add_img.png new file mode 100644 index 0000000000000000000000000000000000000000..27a7795f17e9a7dda9e2dcdb407c87d36d4e44b3 GIT binary patch literal 498 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!jKx9jP7LeL$-D%z*Lb=(hE&A8 zonz>A#6hCHByxJHt{2LfJ9PU}O zH5+g=+b~Hy`KU}h>jekTtS`mOOhx(~>Q^7XTNfnq%kr;m?oHYJU!IyvgY469Mt>{c zTFMsk>iL)QC8^~$DGvAlU%5YRukZeFY2yXvp433t-t@);?y!O=MZ2dGI+ZBxvX literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/item_child_1.png b/app/src/main/res/drawable/item_child_1.png new file mode 100644 index 0000000000000000000000000000000000000000..10f9d762684756dfa9b96ab11da8aa812e05c088 GIT binary patch literal 3151 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 R*n2HtWN`6pnVw_hzW~y_sa^m8 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/item_child_4.png b/app/src/main/res/drawable/item_child_4.png new file mode 100644 index 0000000000000000000000000000000000000000..c6432def5d28c1bf77c10907238ee222afc3dfd3 GIT binary patch literal 3148 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 RGKHfp(9^zgwNleI>R&_ws0IK4 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/item_child_5.png b/app/src/main/res/drawable/item_child_5.png new file mode 100644 index 0000000000000000000000000000000000000000..74a74ba1a287ff0cfea648f1afeb95f4e098fd18 GIT binary patch literal 3144 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 PETFG@`FyFi?d^X7^NOhe literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/item_child_6.png b/app/src/main/res/drawable/item_child_6.png new file mode 100644 index 0000000000000000000000000000000000000000..089be88d3254cb6b000f63502025813300054027 GIT binary patch literal 3152 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/item_img_apps.png b/app/src/main/res/drawable/item_img_apps.png new file mode 100644 index 0000000000000000000000000000000000000000..c3eba533ed0e399a5bc6eebbb664bd0e51983b45 GIT binary patch literal 1418 zcmeAS@N?(olHy`uVBq!ia0vp^GeDSw4M<8HQcwg^jKx9jP7LeL$-HD>V0H0yaSW-5 zdpqZ1?$rbyx3`=c!VJ;}*!D^rFwJc+a!h1;!BWza=V0Ezt05eq_G718<$_DT#j~Fj z|2nO%uQ2h($Bzf6PCAw+BOoADkeK7-d_aJQa|w%pPuKJZ9Bs@&OdM)Qy$e_lGioxj zOn#(l(e$uk3PY3UM#T09-MwGRdhJ#*r&{yP6Ldb`_^K4?-_#oO>SU?MB;)e^ zR$utnZY@vyW_o#z;`QF$@6As9elf+C^IP;E+=di&w5MXxv?X zakpNc(XWe9+1g)H{W`SE?WF~EmWBIl{K9-N%&jlsd!v#>(^?;3KswA!;Al$#2l#0g zX9JeW;E+_4Xi}U34soM{0z3yHLCM*cz@Y{XavuYrQgGCyHYrLpd4j`SnCGB?4>)eH z8F}y8t>8a;pB`^8bBOxg_@MmVKO5_pb82jB#dlsc?^rzl<@RfF{HvLtZHO;A`(pbn z?EM9yuF3 zPkzktJLn$wS$o^-9o0FTXWFzK)hUcWRsBo&cImNiDL(g}xT%+@-f-*j*xkU;q}y17syoLPeDItmR5+z$$0nlQ4=PCFvW&7p9EsUpV8cY*c6wyjfN9T)lNp&%D5vo)u@ z;(=7ZW}J`m{MuvtkBc0xwcRnJqKxfe>s^j*7Z2TC{%e8hJ-s8$*VXI4sN4u!-}Pwa z&x7piq;vQ2t*i*$@~wU?Z+uz5-^RZoce6MR^mns1ZDjdjzv4|s>`jBZhac<$Se!RZ z1qGxA{(y|5R^04<$g=y+`qeh}Au{(}{kHE}uD?6k{`Jce&(-q_&9-eTx-nTWeonf) z`MZ6m{jAjEL8(zO@|oezg6&(s8CMz>Ua{Zx(@OZ9;m%!xI$e@wjxjvm4gP(a1A4q zw#!psP2T%pE%yx~XG$k4MBKf%Jftr{bH-~m#|^vo`mdBZ7-VqWw<)2tdVY{))6#@> zvsn(l`ewJZh{gM0j5%l1)wi`?PdTPF?aUKmS$+HWlv9E_ti^X#IKsAn*PN<6I4yXh Z-{Ro2y-u%cJFswN@O1TaS?83{1OPBpWt;#2 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/item_img_sel.png b/app/src/main/res/drawable/item_img_sel.png new file mode 100644 index 0000000000000000000000000000000000000000..b3c8ac89597df69f42ac09a4e702a3e601e6b67f GIT binary patch literal 1707 zcmV;c22}ZpP)Px*Wl2OqR9HvVnR`&wRTRg+S1}0?*U}_kppb%LfJlmogi1jJ0g{g}4HPCAOwcA3 z%K^tGQ72#JNP~t+F+L)7Ai+opAE1H{6vxMiVuInIfdmS71X}_i8h|+ouV}19c6B}qYEIyC!*x_Q)!^P=wZgi+ zdsxHHVj!HYhhyw>t_ZN11Ut(?5|a|ZRsac%u{wRAdI34-Gaet^20Fr~mS*g`orjIr z(r~i&oIcrV{q729#M;lndxL{u*3FFi2rim2wyQlsIsrN7q^b3y){t9$1Rs~J!o~Wl zMuBM#wzss!mo7>0vzaJ$kv3x(W2D(OO)H=Xw-TH+!dpcH9i$K=KXX+Y6DCK z5J@k+=dYo-`Jl=qaFS44i-9=my&Hp`B?o~N##oGeK{Y_pAa>HRdKJttndUTiOqx9E zy-PaonR3HX0dmgC$=)Dm8&R?t-~N_qQq5@!pJz86siRlX&(#3j7-RH=9B>O+ELrPY zg%STMoV3`1@oAEEZ(xiqQ~`3%$&21lwkpk>^4>ssqb6$}N?H^& z$T?4Z{7l+@GZS-9FMcX;(xMq28!>Zm0DVnnj3r2b^zPYt91ggOHV?&u3l@!z6I_#jg$>7K_r;h$yy5@wtd%%HlTGzY& zW`T5fdk`Q60m)yL@4$l66(#|Uvk%95m*r}*Dr6$yo0*4Z%{T0fybemLcN=#0j*QZ>7g_T@XVwvxGF}f3C^s_ z!Mms8)F91Rcci(m!K@*{YGVn`|M*-Szh`(_A_uGi(6?Xq7*)uwxy2Dy!;t5dE=3%w z?%X>Cm|7Hrrq*Vdck79Ck1r59&|hsjxf7owVYt$8-5|};AW9i(1IaW{M;fGH&w11@ z{_RG~WF+}s8S>mhSdbvYPQ@eR)eZ3LukJ_5xB4HCFba-jy7YF!*~!`T@tn%dOgj;a z%-a;$>TbFq>mJoZ(ZgD8BEk6_4eL-mIcsnb(mmFZJi*O~jyfF+N|W>+13~6ZNQZ-! ztdTQ?A@amvOKq9LSNe7lU7oD0fB{)xYK-B?@8zyK5mdn;LXx4>S{6ij*HH5|KJA{azt%YzQX(Zp}u*C5P$kHC+hk%OYvgbm^CzvN+P5^p>Fg4Njs$-a?XY9j;ab?1=Bm^X!U7J z-cNqD==Dsgy0Dco7A5c3R#~8;kx-YRdo-{x%47*VCG6w{#Hs>aV}Y7QB!h}aF=v-| zc_L4VI#s!hE*{B_nu!JfSvOU=I-4_7w7k|iL0*1K0kBY8Wvh*mXnS|WdJPFt zC|i~I?$&;6F5h8vdP?bJoI?bH2lz@_qq{J^!v#z^tXQ|9+lI6$lt-VGfDhy3ALme3 ze-#xEs#GZhh3r&PbF>-;?|$PDVB;eX)2M1d8(uBdU)nP&y(M4`P%4qkd(0Q!!6N!j z02>Vflh!o~Py<%}H-v)-Y$c8%Crd|oxwC&m{0&Xzu|c*kzJLG#002ovPDHLkV1jW^ BCqw`M literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/item_text_bg.xml b/app/src/main/res/drawable/item_text_bg.xml new file mode 100644 index 0000000..82c5ba0 --- /dev/null +++ b/app/src/main/res/drawable/item_text_bg.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/line.png b/app/src/main/res/drawable/line.png new file mode 100644 index 0000000000000000000000000000000000000000..696264524b32225ed0400ffee175ecd707960aad GIT binary patch literal 2844 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/music.png b/app/src/main/res/drawable/music.png new file mode 100644 index 0000000000000000000000000000000000000000..622f5e1009846edab39ca51daee31728a547c5de GIT binary patch literal 2041 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/tab_apps_normal.png b/app/src/main/res/drawable/tab_apps_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..06b3072782d7306380737ed7e13776e5bb1573eb GIT binary patch literal 1686 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 + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_bg_selector.xml b/app/src/main/res/drawable/tab_bg_selector.xml new file mode 100644 index 0000000..a45732e --- /dev/null +++ b/app/src/main/res/drawable/tab_bg_selector.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_local_normal.png b/app/src/main/res/drawable/tab_local_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..4b20ae4af6067b9fb3a16caa66ca3fba6fd56562 GIT binary patch literal 977 zcmeAS@N?(olHy`uVBq!ia0vp^DImVD9#GaSW-5 zdpl=imPnvT+yBea8X5U3SM1GCWZ~v^t!d`a6xk?b=z74WY0-k#gc|N@FKq&Oi`r$-dh*p$|8@=4VL%{(r@mFDRZT+C=~3 z{Z!7#NfV6kDDCHcpjo-ST>8NFW6m$$Yna!kXT99LDK_l%hGM(m-GAR*TK3gD$NO`J z;{CaDYrh@em7V6_#vbQYY3mWdJ^5og-2&fyneo9S(SeGV3pae)V+)wUMeh(Pr835&vM=Nf|V~? zUbyb;x*5uqS-U%6yWgHit9I`#ouuvU@%pdg-M4GKmugR$V5Oy+(lqh-$>8JlyPTX< zp3G=ir}+6iiz+C9#A2g?VFY4HeVc#l+oTI$eCMJDZC2{;HNP@KTH~fHHt@|?{cmBr z@2z!>!RGeEWlN{@GrXIhdhTL6|JgTPkE^(+clmjIe{5{+x4(ST{l@t}KF&Pv*Wa~U z{HfXXZ^zRYo!j*Jj=G8BbIFh^Z-j(gXT4EYR9UgYh_h44_uE7Pp^%W7EiMz)etU3m zYOV5dTI4agR;7hSG*nG7aLGwKA*ZG;t;rKKE~UtGDmuDO_4E+Q+|=JPVZowPDk@zj kH{G2)0s>P>HugWml^H$FLfkPQfq9g{)78&qol`;+0ICP7IsgCw literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/tab_local_select.png b/app/src/main/res/drawable/tab_local_select.png new file mode 100644 index 0000000000000000000000000000000000000000..f0e5695b5e5e1e317be3020cc265a3e0f1c16148 GIT binary patch literal 911 zcmeAS@N?(olHy`uVBq!ia0vp^DImVD|KMaSW-5 zdpl=imZ+mdtA7)T+dEBCe=G_|%m)-bbjyRLEZQ9R=A5#Yh)Sj$~4s{2-S%ZBT} zo%43+Rlh%X?(h32Pd>3;I{UBqTTOA=w|6|d75}Y~xv?RrS%UFMjsOFTLK@$UlZuKA zhQ$Yb_&6CmW-_N0d2l$KkujL;?8K1ttYM~%5R-s0`oCaATyFdR9v_kakUEVqWuL#wk{q5+&D9rHOiGhn%%`C0C%%pG zL_^>j#WjlRd{_9`maRGTa>WwKV6k8^dmiy#Mj55aU zYF+DMFD*W_eedo`c42++nk zzPbyAe~CD7^Yg#Unc`dLd*1SSp}Z|W z{@a_|>Qmn7Uz9p=Dla9Li}^^8iUT;v=Un6LbhYK1mnt*mx8BQ_b6o$Pe6r!rQ%6>IT)4j6|UKc*U_D$ukf61H8OR_t^icQO!E5LV(cY>|2!XB%a zjm5JZvVNy=n-~6jlDq!n6j!Gio7_@umCr7=>N&P`aY>2$aq*NpD%l=uf7@PXY%y(d z=IcJjz^SOH($b={@x`YpruX;syeu`5YG8PBr193l1MeqX+!_6L1@nonhLkB!7u=bo z_s{FrzPYC=lrxtvei?A-t!nAHIJx`QJEugP&pK{kXD7^l-e_OBQ1t4=n)}Do@2TaA z9(UY%gD>uO|M@La8R^^R-%_7zTz&Z6A;u&(4h1SFL}(hGQ=i}TB2~-XN)wpF7(8A5 KT-G@yGywov^^(2- literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/tab_local_selector.xml b/app/src/main/res/drawable/tab_local_selector.xml new file mode 100644 index 0000000..411e735 --- /dev/null +++ b/app/src/main/res/drawable/tab_local_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_music_normal.png b/app/src/main/res/drawable/tab_music_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..11a7d8ae8669519acf6ad27fa54e770552951aad GIT binary patch literal 1749 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/tab_music_selector.xml b/app/src/main/res/drawable/tab_music_selector.xml new file mode 100644 index 0000000..ac15498 --- /dev/null +++ b/app/src/main/res/drawable/tab_music_selector.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_recommend_normal.png b/app/src/main/res/drawable/tab_recommend_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..7d18954c53415763c609e6a609d9ac64842056af GIT binary patch literal 1752 zcmbuA`8V5%8pgj-6gfdGtz{gsBt@#)Ml+U9sbw%yRZA_gRr%7^)*vX_7!skknAj!~ zdTVV_T2g8m^fE0f$zVt$I+lc#D25u#l#V&~{sD8&{o#F|-=6cF_q^xxAjqGEM3 zwQ$G4)n?A7B%!li%uTNl_uLH-Pb?=rlyt1FiF-JfJWHM?oLwxHuyDyD6PRBykV8NQ z=u({N965OeM=fsA&A}PCT}#3w>Dx(BF*3{!Rk(^R(|C5IoLT_P;~){M4q4L55egRZ zC-e0XANVoll`*twnDLF-54036BVYD%lX z*xVI!3>T?R0x4qt}Lg)=#KPGk^thsq1zF+kmBTXQc{PEeZ7kau8KB%yTs{+vW( z$T2X=t*Y4?0iu+p&PERFo_0yYRX4{?0KnOc~VJtW?Po%2Q9NG zaEh>dwl$F{`j1xIE&jTkh^r3|aQ4Uv7MBpTArBc3%fde`mBW0@XW@gvj+CFMqUTy` z%s&S14n~zDQb3sCMO3o%M*I)u=#25j5HSe)9N9UE5ydP?;Lh~SNJbbwLJJsKxd;d_ z_@geT8m@Jf!18S?ZYY*vL9=A4XzcF{xr&ZM|Blw%_5H6M;krQ?R(W&MGQ(A{Go{DD zzfhmPcZ?b|GBR8fTgSG=coLgF3|`iHzks-tlmw@drUlGGo8Yv>REFuc0JW>aUSTJE zOH1l46lwqO##23!OV5=0v}jiQ+EX53aufyq4I)XD`$+aqav!ol4Ox%6ay78x*a7~f z?Z$-XQgPdQI~I?$%I7j@IJS;AfiX2QE#=~F{%S2cqteFJegBfcBoh~eKQ(1K`Fpgy zU3voIMR!i#%R9W+5akb8Sus*)&f=x|H z3{*S~In(;*__|k9lVSY;&!Gu-5GQyZ10u;n3`RxVOLdS9K3Q=9*jg3`YmK`ed@ z&$B-KbF_TXpHEG;ybWb)?zo26*8l6IPizCDGJCuJ%dCcMstk?uve)=E@uDx*RO3kW z*zMI5ju**`CKLNtE&Fvd`=_hYkBpY*zn}}tFvki%6KSQI?U$_#MsrPrN4KmVev&nW zY0s!z_J2#`=AolX#rWmBsZaCPR0r>~W#>9^xbRUE&GMy*)}r>uD#%{tU-3nsqy|Qc z{3KqdxzI^PfybJPeBCmGHmbwN4DWa=VK*fT>5vX%9W2be0DyuzI(+G7CHn=Z-GG+w zt7Br>tSy=9#*=(|0vk8ey>kYW+HT>ug3MflI;U9QOrJ^p4!l|+^l9kS728Xo&VJr4 ztTopIuolg$@785iv9bF<3#ooWeh=w$5EHnWI3dv?V8%6jO6KA>wT9wvQqSi-=pp&e ziOA!ek?fo?59)(OH{r+@eOKwbAHnVeq+nW-NG^WLVyTq|XBJO3vul2l>9?IcNDa1S z3HR)V#}e&_fBw=`fFkN>Hr#mhJ2CoIHeVt$c)IR@drt|$`Ed0ABJn?i`R-9u3MYZ7 TYLs+XRe+15n?sXb$oGE%4fi@R literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/tab_recommend_select.png b/app/src/main/res/drawable/tab_recommend_select.png new file mode 100644 index 0000000000000000000000000000000000000000..7e0cddcd2db90ef8760b1d7acf4cbfa053d60de3 GIT binary patch literal 1628 zcmbuAdpy$%0L8a?Y$i8EvRNjCawRns-PTxaSS_aJ(Jh5f<~7T!x??g_wis)yA$gU@ zq|%GjmB+7|M~EV6LYv15MMSRqx&Pn$$Nl4+^WXWLzrN?fL6VCG903P`KpF&B=R>P` z@^8UZS3Po=@3k6W#vvCRNZf892Z2=A6P)*X#T}ixN(Q2xbW(<%n7>fLlXdWPHWLTK z!wPkxSW$)M$(xcjaTYoRbDTLY4F@B;4&%r=&Ft$-_!`3?n$R}5;PEF>{NCP2i{lP= z+WS8Yv6SgV`am?Y*{99vI1=?dEJ`P5PbWPk!n z6RGx@M&KrQ@SVs_PLQ-*NRZSyMOkx)ilp(v8Z~qfJcqqb|Gx{0FG8S%-Q=$0ytylP zi;9O#mM!HB!e`ysjScZ!i$yu3f;E4vtJx<{DEG3ZsCK&k)=-p1_H zBhEL09ERtd`{|ne<47=|HF)>ygW|kkV&mx;VX+{1kt&ajMW@D0G*$5KS$Mta3Vb=C z*3-&saP!pev^A4no+z!TQf-;4Gx|d~9BW zh*jS;#p7Bv)%$dLxV7u|m2$AZO%_?X{UUz~X?@|x66Kc``B}ys?mOTW0eivbDRN~I zfzSL{))Z969!z)7^bSf~O-@5Y=G_7Jg4d}I5U?`#Owoq{7i~a)xa!|By`$@^bLAG#j~m&sk?}DL09Xle25?HnZfeQ`0ZD|9vqucB0#-o z{F^z(8P%pWqf;7xYKl|nBQwXx(iQ^+2rg|QQhCOW4BND!@wGKpsot))tcqqY9(|?- zRO8ugq%;&+iJONmxAa1Ue9HzS3O3|!w`miRI9Rtm~eo+rs1?CsNXrJj#;kD_TH zcvk$T_Hw)SXWa6C7Tu55^AH3cXf^GYQu61jC(&+aK8i<##DAox z1dM2hoy+c8{BO{No$XZNR?YDF2ltQk6aqr*6Wwn8+^I*m{8`Cl1taP@EGVMHFY0BN$CtpYBNvEE ztz)P}I#1Lyx56e)zrkWS-(fAMKHo+YIV?Jb9{Dz5j6@LFW9i^1#`t~-W?@U1XRa^= zQQKxL*G+l%IeT-xkiIN`2?nTyYfI9&*7LtvUaM?8azd7F85>c#Yg^^8dh24SM)Hfr ztblMRM6kai=@m^W-R@Efym!kYlQt;5Jo;t+laG=#?=s`|4XT;_;`h^Xvs~Lm2kn^9 z1+G|rrb`>v-4cv%d+H%Yb>Gc%ET8-l){h#}29^iGMjnxm$@p%YM~Whi+viEyOYCbw z)Gj!TkGY=|@Bg%?R_6Lg6vA?YYaS%|{f+N(=+(N{M|Z#X#*$nG9uGkd7=Zip$HMVW zW_Goy-!Xb-tv5}jc+yge!i7V8`x(t`0a@?{-He$jbFQ0Dfdzm5JEl(IveM}Twx}b@ z>Oz)zd#nAr;|n5e<`7jUOV-|l%y`n30L8`e`Vx9-hppr9eKAL3u~msnM;&DwX*VQ# zr+jS#W*2HF?#yj-FF#j+Qq(kuK72O5uSVBQ%q;unbdjb7l&?gnB(Li`>&Yk4Wi$DP z>JEqNHy}A>73F&xsaw&;xE~43Rd&+XqW?cA|CO|}P_6Pefl1Io + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_video_normal.png b/app/src/main/res/drawable/tab_video_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..8b261d4c449d2c9962464c517df3b73f8d6e4f77 GIT binary patch literal 674 zcmeAS@N?(olHy`uVBq!ia0vp^DImV2bf{aSW-5 zdprAfShIrwOZomgKc05D_qGWvo9u9T;-{+@XNJ6e!+S~EK9Hp<#8l+6fRGu7K+^;R zro^Wg6gfDR1;Y4bsljy@GvYaX`^QiJM4nYeetW-v*UDIXKiZl_ajRL&l^(v!isAAl zZx%dkKX2iiV-+#2$k$3zaek0M(Drwi1+Si1>^$rH+wztx$yJvtt7ge5a_sbMaNWDL z?7ZcXoh!s2e>2#<#+8p__*zi^pRkjOV)Xui<5NPdnr+jr;lSTTQ|!`B2_6k1Ln?KV7caKk>{TgAK&WrWO96&QuAtyjY_%kz-@RwaE%D>8YJA9Wd1@PC7Hbs&HJ4j8qa#I=DvN zvE$q+p-utrG+R!mlCWtWEfEHbP0l+XkK+Rhb+ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/tab_video_select.png b/app/src/main/res/drawable/tab_video_select.png new file mode 100644 index 0000000000000000000000000000000000000000..11d1529623e301ae40b6f929524fd7f036c32704 GIT binary patch literal 689 zcmeAS@N?(olHy`uVBq!ia0vp^DImV9NG%aSW-5 zdppa!s5wA@`QypSb8I$h>li$BQV<9%sOC17yR!KE!$RpFp_&D&SG6UvHB2#ObYKWt z<`8LV!J?4LHDzkEGZnZ`&NkNEng4&Y4|C|b#rO0}F9%*fU&i6UV%hNGTAg(Jo~jG) zJMCVkMgCg9ax$Zl6Jtl&`*+qM&mT^>E0pieFyWEsT+1h{bG}&E{`Zy%dLv+ZW9jTv zt9ae3pUhV4G)&=*WYAx`}@zS4vYNeEZNAgvwK;aj&ry* zi-LB8LCVd)TkQgR&(=KI5O>=7-JMTQld9^HlTREAFfZN3U0J$F(&p~R=?+)4v}2{& zLu3LncQ4spaQ>J7*1 zsMvLMkshzgvRk1-^Y@f5bpqTt2BFE + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/video.png b/app/src/main/res/drawable/video.png new file mode 100644 index 0000000000000000000000000000000000000000..359e4f7ff7ac8a8091dd59d606e2d55dc50a20af GIT binary patch literal 965 zcmeAS@N?(olHy`uVBq!ia0vp^DImV6OLcaSW-5 zdpl=gcc`Pp(en)l69PW)Us$)`?1BUVlXvn7CKBdcV$BCPEKqBfVmYf7k<;aNa6w?f z;WBdxocNoe|{le>bt7yI~uVaBn zSyGQ+>c*5%3mHeTl#O7xHrn#plL`FVpSrsz`ORqCYp-g1mZQSs($$sidzVJf3YH7% zs+`oB`0})3$CZCphZ?fzeP{S&`3I zre0j_lYMx+mTh=Sn6|i+w95C+f-~%3ry*ov+TXgwEoG?LAtM< z*os%B?w$Qh>cnL+kt!-+#NO`1UT>o3*p&z2rIJxbxZ@J{f*THlZ84tedu^l{~26 z*tFxx=Q4$f&b#VU_#b}x9WR{GqoM8UxATSO)r~qH&4GOD?Zvc9%+7STs`^9RC@ZF2CgYYvtlE z*Xx5`+Qu5k+2wg(Tg5ECvSw3_#@vt{`&VgpD%!7|IM<+MuQ5-x=G+jSc@`|~0alUe z5};7LGwq9ov9_GYu1i1v>{@bN^mOj)W%1U`%U*LV4}an}f7!hDEo$d7_jszc`LS#} z)}*jjQr6<03d_!&<-AsZdw$5wn=9b-?$zza`+F;=lqRT@{5i|eG{cvL#ZkbR?aYG* l0xX8f2YC4SNZ_8+-?C`$q)AWD$pG^ugQu&X%Q~loCIH3Evflsz literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/wifi1.png b/app/src/main/res/drawable/wifi1.png new file mode 100644 index 0000000000000000000000000000000000000000..82d5c39a825122e08e481db243c0b762070b321d GIT binary patch literal 1689 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 z + + + + + + + + diff --git a/app/src/main/res/layout-sw480dp/add_apps_grid_item.xml b/app/src/main/res/layout-sw480dp/add_apps_grid_item.xml new file mode 100644 index 0000000..7551bf1 --- /dev/null +++ b/app/src/main/res/layout-sw480dp/add_apps_grid_item.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw480dp/apps_grid_item.xml b/app/src/main/res/layout-sw480dp/apps_grid_item.xml new file mode 100644 index 0000000..f40e897 --- /dev/null +++ b/app/src/main/res/layout-sw480dp/apps_grid_item.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw480dp/childgrid_item.xml b/app/src/main/res/layout-sw480dp/childgrid_item.xml new file mode 100644 index 0000000..b622075 --- /dev/null +++ b/app/src/main/res/layout-sw480dp/childgrid_item.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/app/src/main/res/layout-sw480dp/homegrid_item.xml b/app/src/main/res/layout-sw480dp/homegrid_item.xml new file mode 100644 index 0000000..6ad93a5 --- /dev/null +++ b/app/src/main/res/layout-sw480dp/homegrid_item.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/src/main/res/layout-sw480dp/homelist_item.xml b/app/src/main/res/layout-sw480dp/homelist_item.xml new file mode 100644 index 0000000..5c29044 --- /dev/null +++ b/app/src/main/res/layout-sw480dp/homelist_item.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-sw480dp/layout_category_app.xml b/app/src/main/res/layout-sw480dp/layout_category_app.xml new file mode 100644 index 0000000..bd19cc0 --- /dev/null +++ b/app/src/main/res/layout-sw480dp/layout_category_app.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw480dp/layout_custom_apps1.xml b/app/src/main/res/layout-sw480dp/layout_custom_apps1.xml new file mode 100644 index 0000000..dde2b50 --- /dev/null +++ b/app/src/main/res/layout-sw480dp/layout_custom_apps1.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/app/src/main/res/layout-sw480dp/layout_rect_group1.xml b/app/src/main/res/layout-sw480dp/layout_rect_group1.xml new file mode 100644 index 0000000..15b5a15 --- /dev/null +++ b/app/src/main/res/layout-sw480dp/layout_rect_group1.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw480dp/layout_shortcut.xml b/app/src/main/res/layout-sw480dp/layout_shortcut.xml new file mode 100644 index 0000000..62a605f --- /dev/null +++ b/app/src/main/res/layout-sw480dp/layout_shortcut.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/app/src/main/res/layout-sw480dp/layout_statusbar.xml b/app/src/main/res/layout-sw480dp/layout_statusbar.xml new file mode 100644 index 0000000..0c3ab3b --- /dev/null +++ b/app/src/main/res/layout-sw480dp/layout_statusbar.xml @@ -0,0 +1,39 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-sw480dp/main.xml b/app/src/main/res/layout-sw480dp/main.xml new file mode 100644 index 0000000..b65ab4f --- /dev/null +++ b/app/src/main/res/layout-sw480dp/main.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw480dp/multi_layout.xml b/app/src/main/res/layout-sw480dp/multi_layout.xml new file mode 100644 index 0000000..618774d --- /dev/null +++ b/app/src/main/res/layout-sw480dp/multi_layout.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/app/src/main/res/layout-sw540dp/ad_multi_layout.xml b/app/src/main/res/layout-sw540dp/ad_multi_layout.xml new file mode 100644 index 0000000..dd02c99 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/ad_multi_layout.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/app/src/main/res/layout-sw540dp/add_apps_grid_item.xml b/app/src/main/res/layout-sw540dp/add_apps_grid_item.xml new file mode 100644 index 0000000..2ac63c3 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/add_apps_grid_item.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw540dp/apps_grid_item.xml b/app/src/main/res/layout-sw540dp/apps_grid_item.xml new file mode 100644 index 0000000..7286281 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/apps_grid_item.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw540dp/childgrid_item.xml b/app/src/main/res/layout-sw540dp/childgrid_item.xml new file mode 100644 index 0000000..47e24e0 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/childgrid_item.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/app/src/main/res/layout-sw540dp/homegrid_item.xml b/app/src/main/res/layout-sw540dp/homegrid_item.xml new file mode 100644 index 0000000..ef84703 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/homegrid_item.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/src/main/res/layout-sw540dp/homelist_item.xml b/app/src/main/res/layout-sw540dp/homelist_item.xml new file mode 100644 index 0000000..dbd7c22 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/homelist_item.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-sw540dp/layout_category_app.xml b/app/src/main/res/layout-sw540dp/layout_category_app.xml new file mode 100644 index 0000000..845a27e --- /dev/null +++ b/app/src/main/res/layout-sw540dp/layout_category_app.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw540dp/layout_custom_apps1.xml b/app/src/main/res/layout-sw540dp/layout_custom_apps1.xml new file mode 100644 index 0000000..2c57122 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/layout_custom_apps1.xml @@ -0,0 +1,19 @@ + + + + diff --git a/app/src/main/res/layout-sw540dp/layout_rect_group1.xml b/app/src/main/res/layout-sw540dp/layout_rect_group1.xml new file mode 100644 index 0000000..13f0a0a --- /dev/null +++ b/app/src/main/res/layout-sw540dp/layout_rect_group1.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw540dp/layout_shortcut.xml b/app/src/main/res/layout-sw540dp/layout_shortcut.xml new file mode 100644 index 0000000..f65d5f7 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/layout_shortcut.xml @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/app/src/main/res/layout-sw540dp/layout_statusbar.xml b/app/src/main/res/layout-sw540dp/layout_statusbar.xml new file mode 100644 index 0000000..a5757a5 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/layout_statusbar.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-sw540dp/main.xml b/app/src/main/res/layout-sw540dp/main.xml new file mode 100644 index 0000000..82863de --- /dev/null +++ b/app/src/main/res/layout-sw540dp/main.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw540dp/multi_layout.xml b/app/src/main/res/layout-sw540dp/multi_layout.xml new file mode 100644 index 0000000..5d54be7 --- /dev/null +++ b/app/src/main/res/layout-sw540dp/multi_layout.xml @@ -0,0 +1,36 @@ + + + + + + + + + diff --git a/app/src/main/res/layout-sw720dp/ad_multi_layout.xml b/app/src/main/res/layout-sw720dp/ad_multi_layout.xml new file mode 100644 index 0000000..a2f98a1 --- /dev/null +++ b/app/src/main/res/layout-sw720dp/ad_multi_layout.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/app/src/main/res/layout-sw720dp/add_apps_grid_item.xml b/app/src/main/res/layout-sw720dp/add_apps_grid_item.xml new file mode 100644 index 0000000..f7a7ab5 --- /dev/null +++ b/app/src/main/res/layout-sw720dp/add_apps_grid_item.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw720dp/apps_grid_item.xml b/app/src/main/res/layout-sw720dp/apps_grid_item.xml new file mode 100644 index 0000000..367b752 --- /dev/null +++ b/app/src/main/res/layout-sw720dp/apps_grid_item.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw720dp/childgrid_item.xml b/app/src/main/res/layout-sw720dp/childgrid_item.xml new file mode 100644 index 0000000..f4de8a2 --- /dev/null +++ b/app/src/main/res/layout-sw720dp/childgrid_item.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/app/src/main/res/layout-sw720dp/homegrid_item.xml b/app/src/main/res/layout-sw720dp/homegrid_item.xml new file mode 100644 index 0000000..9cf6b8b --- /dev/null +++ b/app/src/main/res/layout-sw720dp/homegrid_item.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/src/main/res/layout-sw720dp/homelist_item.xml b/app/src/main/res/layout-sw720dp/homelist_item.xml new file mode 100644 index 0000000..a81d716 --- /dev/null +++ b/app/src/main/res/layout-sw720dp/homelist_item.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-sw720dp/layout_category_app.xml b/app/src/main/res/layout-sw720dp/layout_category_app.xml new file mode 100644 index 0000000..4006e3e --- /dev/null +++ b/app/src/main/res/layout-sw720dp/layout_category_app.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw720dp/layout_custom_apps1.xml b/app/src/main/res/layout-sw720dp/layout_custom_apps1.xml new file mode 100644 index 0000000..2d4b17b --- /dev/null +++ b/app/src/main/res/layout-sw720dp/layout_custom_apps1.xml @@ -0,0 +1,20 @@ + + + + diff --git a/app/src/main/res/layout-sw720dp/layout_rect_group1.xml b/app/src/main/res/layout-sw720dp/layout_rect_group1.xml new file mode 100644 index 0000000..53d1578 --- /dev/null +++ b/app/src/main/res/layout-sw720dp/layout_rect_group1.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw720dp/layout_shortcut.xml b/app/src/main/res/layout-sw720dp/layout_shortcut.xml new file mode 100644 index 0000000..120798b --- /dev/null +++ b/app/src/main/res/layout-sw720dp/layout_shortcut.xml @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/app/src/main/res/layout-sw720dp/layout_statusbar.xml b/app/src/main/res/layout-sw720dp/layout_statusbar.xml new file mode 100644 index 0000000..6998ab2 --- /dev/null +++ b/app/src/main/res/layout-sw720dp/layout_statusbar.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-sw720dp/main.xml b/app/src/main/res/layout-sw720dp/main.xml new file mode 100644 index 0000000..62417d9 --- /dev/null +++ b/app/src/main/res/layout-sw720dp/main.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw720dp/multi_layout.xml b/app/src/main/res/layout-sw720dp/multi_layout.xml new file mode 100644 index 0000000..e1c971f --- /dev/null +++ b/app/src/main/res/layout-sw720dp/multi_layout.xml @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/activity_my.xml b/app/src/main/res/layout/activity_my.xml new file mode 100644 index 0000000..0c8ed54 --- /dev/null +++ b/app/src/main/res/layout/activity_my.xml @@ -0,0 +1,29 @@ + + +