FoodCookingApp.kt 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. package com.develop.foodcooking
  2. import android.annotation.SuppressLint
  3. import android.content.Context
  4. import android.content.Intent
  5. import android.content.res.Configuration
  6. import android.net.Uri
  7. import android.os.Build
  8. import android.os.PowerManager
  9. import android.provider.Settings
  10. import android.util.Log
  11. import com.blankj.utilcode.util.AppUtils
  12. import com.blankj.utilcode.util.PathUtils
  13. import com.blankj.utilcode.util.ResourceUtils
  14. import com.blankj.utilcode.util.Utils
  15. import com.develop.base.app.BaseApp
  16. import com.develop.base.ext.getBrandNum
  17. import com.develop.base.ext.setAppCode
  18. import com.develop.base.ext.setIsBrand011A
  19. import com.develop.base.ext.setIsBrand036I
  20. import com.develop.base.ext.setIsBrand054A
  21. import com.develop.base.ext.setIsBrand062
  22. import com.develop.base.ext.setNightTheme
  23. import com.develop.base.util.MMkvUtils
  24. import com.develop.common.bean.TuyaEvent
  25. import com.develop.common.data_repo.FoodDataProvider
  26. import com.develop.common.data_repo.net.Api
  27. import com.develop.common.data_repo.net.converter.SerializationConverter
  28. import com.develop.common.data_repo.net.interceptor.FoodRequestInterceptor
  29. import com.develop.common.food_sdk.GlobalDevEvent
  30. import com.develop.common.food_sdk.SerialPortUtils
  31. import com.develop.common.tag.MODEL
  32. import com.develop.common.utils.TuyaUtils
  33. import com.develop.common.utils.compat.RecyclerViewCompat
  34. import com.develop.common.utils.compat.ShapeableImageViewCompat
  35. import com.develop.common.utils.compat.SmartRefreshLayoutCompat
  36. import com.develop.common.utils.compat.StartViewCompat
  37. import com.drake.net.convert.NetConverter
  38. import com.drake.net.interceptor.RequestInterceptor
  39. import com.drake.net.interfaces.NetErrorHandler
  40. import com.drake.net.time.Interval
  41. import com.kuyuntech.cofarcooking.device.sdk.constant.core.DevStatus
  42. import com.kuyuntech.cofarcooking.device.sdk.eventbus.event.DevPromptEvent
  43. import com.kuyuntech.cofarcooking.device.sdk.eventbus.event.DevStatusEvent
  44. import com.kuyuntech.cofarcooking.device.sdk.util.core.CofarSDK
  45. import org.alee.component.skin.compat.ConstraintLayoutCompat
  46. import org.alee.component.skin.page.WindowManager
  47. import org.alee.component.skin.service.Config
  48. import org.alee.component.skin.service.IOptionFactory
  49. import org.alee.component.skin.service.IThemeSkinOption
  50. import org.alee.component.skin.service.ThemeSkinService
  51. import org.greenrobot.eventbus.EventBus
  52. import org.greenrobot.eventbus.Subscribe
  53. import java.io.File
  54. import java.lang.reflect.Method
  55. import java.security.cert.X509Certificate
  56. import java.util.Locale
  57. import java.util.concurrent.TimeUnit
  58. import javax.net.ssl.TrustManager
  59. class FoodCookingApp : BaseApp() {
  60. companion object {
  61. init {
  62. Config.getInstance().skinMode = Config.SkinMode.REPLACE_ALL
  63. Config.getInstance().performanceMode = Config.PerformanceMode.EXPERIENCE_FIRST
  64. ConstraintLayoutCompat.init()
  65. RecyclerViewCompat.init()
  66. SmartRefreshLayoutCompat.init()
  67. ShapeableImageViewCompat.init()
  68. StartViewCompat.init()
  69. }
  70. }
  71. var mWakeLock: PowerManager.WakeLock? = null
  72. private lateinit var pm: PowerManager
  73. var minute = 0
  74. private var heartBeatInterval: Interval? = null
  75. var ledLock = false
  76. override fun onCreate() {
  77. hookWebView()
  78. super.onCreate()
  79. //处理崩溃问题
  80. // CrashHandler.getInstance().init(this);
  81. //FoodDataProvider.initFoodDataBase()
  82. WindowManager.getInstance().init(this, OptionFactory())
  83. setAppCode(BuildConfig.appCode)
  84. val isNight = BuildConfig.UpdatePlatform.equals("night")
  85. val is062 = BuildConfig.UpdatePlatform.equals("062A")
  86. val is011 = BuildConfig.UpdatePlatform.equals("011A")
  87. setIsBrand036I(BuildConfig.UpdatePlatform.equals("036I"))
  88. setIsBrand054A(BuildConfig.UpdatePlatform.equals("054A"))
  89. setIsBrand011A(is011)
  90. setIsBrand062(is062)
  91. if (BuildConfig.brandCode.startsWith("010")){
  92. MMkvUtils.save("appTime", BuildConfig.time)
  93. }
  94. if (is062) {
  95. ResourceUtils.copyFileFromAssets(
  96. ASSETS_BLUE_SKIN_PACK,
  97. SKIN_PACK_PATH + BLUE_SKIN_PACK_NAME
  98. )
  99. }
  100. if (is011) {
  101. ResourceUtils.copyFileFromAssets(
  102. ASSETS_ZERO_ONE_ONE_SKIN_PACK,
  103. SKIN_PACK_PATH + ZERO_ONE_ONE_SKIN_PACK_NAME
  104. )
  105. }
  106. if (isNight) {
  107. ResourceUtils.copyFileFromAssets(
  108. ASSETS_NIGHT_SKIN_PACK,
  109. SKIN_PACK_PATH + NIGHT_SKIN_PACK_NAME
  110. )
  111. }
  112. //切换主题,theme=0 night= false 是0000的主题,而且需要AndroidManifest.xml主题设置为 android:theme="@style/SplashTheme"
  113. ThemeSkinService.getInstance()
  114. .switchThemeSkin(if (isNight) 1 else if (is062) 2 else if (is011) 3 else 0)
  115. setNightTheme(isNight)
  116. CofarSDK.init(getBrandNum())
  117. SerialPortUtils.init()
  118. CofarSDK.register(this)
  119. CofarSDK.stopNative()
  120. // val powerManager = getSystemService(POWER_SERVICE) as PowerManager
  121. // val wakeLock: PowerManager.WakeLock =
  122. // powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "motionDetection:keepAwake")
  123. // wakeLock.acquire()
  124. pm = getSystemService(POWER_SERVICE) as PowerManager
  125. minute = MMkvUtils.getInt("ScreenSaver")
  126. if (minute == 0) {
  127. minute = 5
  128. }
  129. Settings.System.putInt(
  130. contentResolver,
  131. Settings.System.SCREEN_OFF_TIMEOUT,
  132. (1000 * 60 * minute).toInt()
  133. )
  134. Settings.Secure.putInt(contentResolver, Settings.Secure.INSTALL_NON_MARKET_APPS, 1)
  135. val uri: Uri = Settings.System
  136. .getUriFor(Settings.System.SCREEN_OFF_TIMEOUT)
  137. contentResolver.notifyChange(uri, null)
  138. heartBeatInterval = Interval(1, 1, TimeUnit.SECONDS, 5).finish {
  139. //设备不通讯异常
  140. EventBus.getDefault().post(
  141. DevPromptEvent.builder()
  142. .showCancelBtn(false)
  143. .msg("dev_error")
  144. .focus(true)
  145. .build()
  146. )
  147. }.start()
  148. }
  149. fun hookWebView() {
  150. val TAG = "ASDD"
  151. val sdkInt = Build.VERSION.SDK_INT
  152. try {
  153. val factoryClass = Class.forName("android.webkit.WebViewFactory")
  154. val field = factoryClass.getDeclaredField("sProviderInstance")
  155. field.isAccessible = true
  156. var sProviderInstance = field[null]
  157. if (sProviderInstance != null) {
  158. Log.d(TAG, "sProviderInstance isn't null")
  159. return
  160. }
  161. val getProviderClassMethod: Method
  162. getProviderClassMethod = if (sdkInt > 22) {
  163. factoryClass.getDeclaredMethod("getProviderClass")
  164. } else if (sdkInt == 22) {
  165. factoryClass.getDeclaredMethod("getFactoryClass")
  166. } else {
  167. Log.d(TAG, "Don't need to Hook WebView")
  168. return
  169. }
  170. getProviderClassMethod.isAccessible = true
  171. val providerClass = getProviderClassMethod.invoke(factoryClass) as Class<*>
  172. val delegateClass = Class.forName("android.webkit.WebViewDelegate")
  173. val providerConstructor = providerClass.getConstructor(delegateClass)
  174. if (providerConstructor != null) {
  175. providerConstructor.isAccessible = true
  176. val declaredConstructor = delegateClass.getDeclaredConstructor()
  177. declaredConstructor.isAccessible = true
  178. sProviderInstance =
  179. providerConstructor.newInstance(declaredConstructor.newInstance())
  180. field["sProviderInstance"] = sProviderInstance
  181. }
  182. Log.d(TAG, "Hook done!")
  183. } catch (e: Throwable) {
  184. }
  185. }
  186. override fun createHostUrl(): String {
  187. return Api.HOST
  188. }
  189. override fun createRequestInterceptor(): RequestInterceptor {
  190. return FoodRequestInterceptor()
  191. }
  192. override fun createConverter(): NetConverter {
  193. return SerializationConverter()
  194. }
  195. override fun createErrorHandle(): NetErrorHandler {
  196. return NetErrorHandler.DEFAULT
  197. }
  198. override fun attachBaseContext(base: Context?) {
  199. super.attachBaseContext(base)
  200. FoodDataProvider.prepareData(this)
  201. }
  202. override fun onTerminate() {
  203. super.onTerminate()
  204. SerialPortUtils.destroy()
  205. CofarSDK.unregister(this)
  206. }
  207. @SuppressLint("InvalidWakeLockTag")
  208. @Subscribe
  209. fun onTuyaEvent(event: TuyaEvent) {
  210. TuyaUtils.uploadData()
  211. heartBeatInterval?.cancel()
  212. val pm = getSystemService(POWER_SERVICE) as PowerManager
  213. if (mWakeLock == null) {
  214. mWakeLock = pm.newWakeLock(
  215. PowerManager.SCREEN_BRIGHT_WAKE_LOCK or PowerManager.ON_AFTER_RELEASE or PowerManager.ACQUIRE_CAUSES_WAKEUP,
  216. "tag"
  217. );
  218. mWakeLock?.setReferenceCounted(false);
  219. mWakeLock?.acquire()
  220. }
  221. mWakeLock?.release()
  222. mWakeLock = null
  223. val intent = Intent()
  224. intent.action = "android.intent.action.SS_DEVICE_TOUCH"
  225. sendBroadcast(intent)
  226. }
  227. // @Subscribe
  228. // fun onCookDevMsgEvent(event: DevPromptEvent) {
  229. //
  230. //
  231. // }
  232. @SuppressLint("InvalidWakeLockTag")
  233. @Subscribe
  234. @Synchronized
  235. fun globalCoverEvent(event: DevStatusEvent) {
  236. TuyaUtils.uploadData()
  237. heartBeatInterval?.cancel()
  238. val devInfo = event.devInfo;
  239. val pm = getSystemService(POWER_SERVICE) as PowerManager
  240. if (devInfo.status == DevStatus.RUNNING.toInt() || devInfo.isWeightStatus) {
  241. if (mWakeLock == null) {
  242. mWakeLock = pm.newWakeLock(
  243. PowerManager.SCREEN_BRIGHT_WAKE_LOCK or PowerManager.ON_AFTER_RELEASE or PowerManager.ACQUIRE_CAUSES_WAKEUP,
  244. "tag"
  245. );
  246. mWakeLock?.setReferenceCounted(false);
  247. mWakeLock?.acquire()
  248. }
  249. } else if (devInfo.status != DevStatus.RUNNING.toInt()) {
  250. if (mWakeLock != null) {
  251. mWakeLock?.release()
  252. mWakeLock = null
  253. val intent = Intent()
  254. intent.action = "android.intent.action.SS_DEVICE_TOUCH"
  255. sendBroadcast(intent)
  256. }
  257. }
  258. // if (!ledLock) {
  259. // //devInfo.potStatus 0是有锅 1是没锅
  260. // //devInfo.potCloverStatus 0是合盖,1是没盒盖
  261. // ledLock = true;
  262. // //屏幕暗
  263. // if (!pm.isScreenOn) {
  264. //
  265. // //合盖
  266. // if (devInfo.potCloverStatus.toInt() == 0) {
  267. // CofarSDK.flashWhiteRedLed()
  268. // } else {
  269. // CofarSDK.switchWhiteLed('0');
  270. // CofarSDK.flashRedLed()
  271. // }
  272. //
  273. // } else {
  274. // //屏幕亮
  275. // if (devInfo.status == DevStatus.STOP.toInt()) {
  276. //
  277. // if (devInfo.potStatus.toInt() == 0) {
  278. // if (devInfo.potCloverStatus.toInt() == 0) {
  279. // CofarSDK.flashWhiteRedLed()
  280. // } else {
  281. // CofarSDK.switchWhiteLed('0');
  282. // CofarSDK.flashRedLed()
  283. // }
  284. // } else {
  285. // CofarSDK.switchWhiteLed('0');
  286. // CofarSDK.flashRedLed();
  287. // }
  288. //
  289. // }
  290. //
  291. // if (devInfo.status == DevStatus.RUNNING.toInt()) {
  292. //
  293. // if (devInfo.temp < 60) {
  294. // CofarSDK.switchRedLed('0');
  295. // CofarSDK.switchWhiteLed('1');
  296. // } else {
  297. // CofarSDK.switchRedLed('1');
  298. // CofarSDK.switchWhiteLed('0');
  299. // }
  300. //
  301. // }
  302. //
  303. // if (devInfo.status == DevStatus.PAUSE.toInt()) {
  304. //
  305. // //判断盖子是否打开
  306. // //合盖
  307. // if (devInfo.potCloverStatus.toInt() == 1) {
  308. // CofarSDK.switchWhiteLed('0');
  309. // CofarSDK.flashRedLed()
  310. // } else {
  311. // CofarSDK.flashWhiteRedLed()
  312. // }
  313. //
  314. //
  315. // }
  316. // }
  317. // ledLock = false;
  318. // }
  319. GlobalDevEvent.globalCoverEvent(event, pm)
  320. }
  321. }
  322. class OptionFactory : IOptionFactory {
  323. override fun defaultTheme(): Int {
  324. return 0
  325. }
  326. override fun requireOption(theme: Int): IThemeSkinOption? {
  327. return when (theme) {
  328. 1 -> NightOption()
  329. 2 -> BlueOption()
  330. 3 -> ZeroOneOneOption()
  331. else -> null
  332. }
  333. }
  334. }
  335. class NightOption : IThemeSkinOption {
  336. override fun getStandardSkinPackPath(): LinkedHashSet<String> {
  337. val pathSet = LinkedHashSet<String>()
  338. pathSet.add(SKIN_PACK_PATH + NIGHT_SKIN_PACK_NAME)
  339. return pathSet
  340. }
  341. }
  342. class BlueOption : IThemeSkinOption {
  343. override fun getStandardSkinPackPath(): LinkedHashSet<String> {
  344. val pathSet = LinkedHashSet<String>()
  345. pathSet.add(SKIN_PACK_PATH + BLUE_SKIN_PACK_NAME)
  346. return pathSet
  347. }
  348. }
  349. class ZeroOneOneOption : IThemeSkinOption {
  350. override fun getStandardSkinPackPath(): LinkedHashSet<String> {
  351. val pathSet = LinkedHashSet<String>()
  352. pathSet.add(SKIN_PACK_PATH + ZERO_ONE_ONE_SKIN_PACK_NAME)
  353. return pathSet
  354. }
  355. }
  356. const val NIGHT_SKIN_PACK_NAME = "night.skin"
  357. const val ASSETS_NIGHT_SKIN_PACK = "skins/night.skin"
  358. const val BLUE_SKIN_PACK_NAME = "blue.skin"
  359. const val ASSETS_BLUE_SKIN_PACK = "skins/blue.skin"
  360. const val ZERO_ONE_ONE_SKIN_PACK_NAME = "zeroOneOne.skin"
  361. const val ASSETS_ZERO_ONE_ONE_SKIN_PACK = "skins/zeroOneOne.skin"
  362. /**
  363. * 应用存储空间根路径
  364. */
  365. private val ROOT_PATH =
  366. Utils.getApp().getExternalFilesDir(null)?.absolutePath?.run { this + File.separator }
  367. ?: (PathUtils.getExternalAppDataPath() + "." + AppUtils.getAppPackageName() + File.separator)
  368. /**
  369. * 皮肤包根路径
  370. */
  371. val SKIN_PACK_PATH = ROOT_PATH + ".SkinPack" + File.separator