电子屏项目
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

460 строки
15 KiB

  1. package com.yzx.webebook.activity
  2. import android.annotation.SuppressLint
  3. import android.app.Activity
  4. import android.app.AlertDialog
  5. import android.app.Dialog
  6. import android.content.Context
  7. import android.content.Intent
  8. import android.net.http.SslError
  9. import android.os.Build
  10. import android.text.TextUtils
  11. import android.util.Log
  12. import android.view.View
  13. import android.view.ViewGroup
  14. import android.webkit.*
  15. import android.widget.LinearLayout
  16. import android.widget.ProgressBar
  17. import android.widget.TextView
  18. import androidx.annotation.RequiresApi
  19. import androidx.core.widget.ContentLoadingProgressBar
  20. import com.allenliu.versionchecklib.callback.APKDownloadListener
  21. import com.allenliu.versionchecklib.v2.AllenVersionChecker
  22. import com.allenliu.versionchecklib.v2.builder.UIData
  23. import com.allenliu.versionchecklib.v2.callback.CustomDownloadingDialogListener
  24. import com.blankj.utilcode.util.AppUtils
  25. import com.blankj.utilcode.util.SPUtils
  26. import com.google.gson.Gson
  27. import com.google.gson.reflect.TypeToken
  28. import com.lzy.okgo.OkGo
  29. import com.lzy.okgo.callback.StringCallback
  30. import com.lzy.okgo.model.Response
  31. import com.yzx.webebook.MainActivity
  32. import com.yzx.webebook.R
  33. import com.yzx.webebook.activity.base.BaseActivity
  34. import com.yzx.webebook.model.BaseBean
  35. import com.yzx.webebook.model.Version
  36. import com.yzx.webebook.presenter.base.BasePresenter
  37. import com.yzx.webebook.widget.BaseDialog
  38. import kotlinx.android.synthetic.main.activity_web.*
  39. import org.jetbrains.anko.ctx
  40. import org.jetbrains.anko.find
  41. import org.jetbrains.anko.startActivity
  42. import org.jetbrains.anko.toast
  43. import org.json.JSONObject
  44. import java.io.File
  45. import java.util.*
  46. /**
  47. * 类名:WebActivity
  48. * 作者:Yun.Lei
  49. * 功能:
  50. * 创建日期:2020年5月6日14:42:16
  51. * 修改人:
  52. * 修改时间:
  53. * 修改备注:
  54. */
  55. class WebActivity : BaseActivity<BasePresenter<*>>() {
  56. companion object {
  57. fun active(act: Activity, link: String) {
  58. act.startActivity<WebActivity>("link" to link)
  59. }
  60. }
  61. private val webView: WebView by lazy { WebView(this) }
  62. private var url: String = ""
  63. private var count = 0
  64. private val run = Runnable {
  65. count = 0
  66. }
  67. override val inflateId: Int
  68. get() = R.layout.activity_web
  69. override fun onNewIntent(intent: Intent?) {
  70. super.onNewIntent(intent)
  71. url = intent?.getStringExtra("link") ?: "https://m.qbjjyyun.net/"
  72. this.initData()
  73. }
  74. fun checkVersion(userCheck: Boolean = false): Unit {
  75. val test = "192.168.69.112:9009"
  76. val online = "https://oa.qbjjyyun.net/api"
  77. val BASE_URL = online
  78. OkGo.post<String>("$BASE_URL/parent/common/getInkBottleMaxVersion")
  79. .tag(this)
  80. .execute(object : StringCallback() {
  81. override fun onSuccess(response: Response<String>) {
  82. val json = response.body()
  83. Log.d("checkVersion", "onSuccess: ${json}")
  84. val resultType = object : TypeToken<BaseBean<Version>>() {}.type
  85. val gson = Gson()
  86. val res = gson.fromJson<BaseBean<Version>>(json, resultType)
  87. if (res.code == 0) {
  88. val appVersion = AppUtils.getAppVersionName()
  89. val appVersionCode = AppUtils.getAppVersionCode()
  90. val versionCode = res?.data?.version_code ?: 0
  91. val curr = Date().time
  92. val lastTipTime = SPUtils.getInstance()
  93. .getLong("last_tip_time${res.data.version_code}", 0)
  94. if (versionCode > appVersionCode) { //有新版本
  95. when {
  96. res.data.type == 1 -> { //强制升级
  97. updateApp(res.data)
  98. }
  99. curr - lastTipTime > 24 * 60 * 60 * 1000 -> { //非强制一天以内提示一次
  100. updateApp(res.data)
  101. }
  102. userCheck -> { //
  103. updateApp(res.data)
  104. }
  105. }
  106. } else {
  107. if (userCheck) {
  108. toast("已经是最新版本了!")
  109. }
  110. }
  111. }
  112. }
  113. })
  114. }
  115. private fun updateApp(version: Version) {
  116. AllenVersionChecker
  117. .getInstance()
  118. .downloadOnly(
  119. UIData.create()
  120. .setTitle("检测到新版本")
  121. .setContent(version.explain)
  122. // .setDownloadUrl("https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/Yzx_2.0.0.apk")
  123. // .setDownloadUrl("https://filea.oa.qbjjyyun.net/edufile/202102/5986/27a58c0b85cb42aee37ce85fe956b743.apk")
  124. .setDownloadUrl(version.app_src)
  125. )
  126. .setCustomVersionDialogListener { context, versionBundle ->
  127. val dialog = BaseDialog(context, R.style.BaseDialog, R.layout.version_dialog)
  128. val title = dialog.find<TextView>(R.id.tv_title)
  129. title.text = "检测到新版本"
  130. val content = dialog.find<TextView>(R.id.tv_msg)
  131. content.text = version.explain
  132. dialog.window?.setDimAmount(0.5f)
  133. val cancelBtn = dialog.find<View>(R.id.cancel_btn)
  134. if (version.type == 1) {
  135. cancelBtn.visibility = View.GONE
  136. }
  137. return@setCustomVersionDialogListener dialog
  138. }
  139. .setOnCancelListener {
  140. SPUtils.getInstance().put("last_tip_time${version.version_code}", Date().time)
  141. }
  142. .setCustomDownloadingDialogListener(object : CustomDownloadingDialogListener {
  143. @SuppressLint("SetTextI18n")
  144. override fun updateUI(dialog: Dialog?, progress: Int, versionBundle: UIData?) {
  145. val tvProgress: TextView = dialog!!.findViewById(R.id.tv_progress)
  146. val progressBar: ContentLoadingProgressBar = dialog.findViewById(R.id.pb)
  147. progressBar.progress = progress
  148. tvProgress.text = "$progress%"
  149. Log.d("checkVersion", "onSuccess: ${progress}")
  150. }
  151. override fun getCustomDownloadingDialog(
  152. context: Context?,
  153. progress: Int,
  154. versionBundle: UIData?
  155. ): Dialog {
  156. return BaseDialog(
  157. context!!,
  158. R.style.BaseDialog,
  159. R.layout.download_dialog
  160. )
  161. }
  162. })
  163. .executeMission(this)
  164. }
  165. @SuppressLint("SetJavaScriptEnabled")
  166. override fun initView() {
  167. url = intent?.getStringExtra("link") ?: "https://m.qbjjyyun.net/"
  168. titleTv.setOnClickListener {
  169. count++
  170. titleTv.removeCallbacks(run)
  171. titleTv.postDelayed(run, 1000)
  172. if (count >= 5) {
  173. startActivity<MainActivity>()
  174. }
  175. }
  176. btnBack.setOnClickListener { onBackPressed() }
  177. btnClose.setOnClickListener {
  178. webView.loadUrl(url)
  179. }
  180. btnRefresh.setOnClickListener {
  181. webView.reload()
  182. }
  183. webView.layoutParams = LinearLayout.LayoutParams(
  184. ViewGroup.LayoutParams.MATCH_PARENT,
  185. ViewGroup.LayoutParams.MATCH_PARENT
  186. )
  187. webLayout.addView(webView)
  188. webView.addJavascriptInterface(YzxJavascriptInterface(this), "YZX")
  189. val userAgent = webView.settings.userAgentString
  190. webView.settings.apply {
  191. allowFileAccess = true
  192. javaScriptEnabled = true
  193. loadWithOverviewMode = true
  194. useWideViewPort = true
  195. defaultTextEncodingName = "gb2312"
  196. setAppCacheEnabled(true)
  197. mediaPlaybackRequiresUserGesture = false
  198. javaScriptCanOpenWindowsAutomatically = true
  199. cacheMode = WebSettings.LOAD_DEFAULT
  200. databaseEnabled = true
  201. setRenderPriority(WebSettings.RenderPriority.HIGH)
  202. blockNetworkImage = false
  203. domStorageEnabled = true
  204. setAppCacheMaxSize(1024 * 1024 * 8)
  205. setAppCachePath(ctx.cacheDir.absolutePath)
  206. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  207. mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
  208. }
  209. userAgentString = "$userAgent app/ebook"
  210. }
  211. webView.webViewClient = object : WebViewClient() {
  212. @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
  213. override fun shouldOverrideUrlLoading(
  214. view: WebView?,
  215. request: WebResourceRequest?
  216. ): Boolean {
  217. view?.loadUrl(request?.url.toString())
  218. return super.shouldOverrideUrlLoading(view, request)
  219. }
  220. // 即使加载失败后,webview执行完onReceivedError()方法也会执行这个方法
  221. override fun onPageFinished(view: WebView, url: String) {
  222. super.onPageFinished(view, url)
  223. webView.settings.blockNetworkImage = false
  224. if (!TextUtils.isEmpty(view.title)) {
  225. titleTv.text = view.title//webView获取到网页title
  226. }
  227. }
  228. override fun onReceivedSslError(
  229. view: WebView,
  230. handler: SslErrorHandler,
  231. error: SslError
  232. ) {
  233. handler.proceed()
  234. }
  235. }
  236. webView.webChromeClient = object : WebChromeClient() {
  237. override fun onProgressChanged(view: WebView?, newProgress: Int) {
  238. super.onProgressChanged(view, newProgress)
  239. progressbar.progress = newProgress
  240. if (newProgress >= 100) {
  241. view?.post {
  242. progressbar.visibility = View.GONE
  243. if (view.canGoBack()) {
  244. btnBack.visibility = View.VISIBLE
  245. // btnClose.visibility = View.VISIBLE
  246. } else {
  247. btnBack.visibility = View.GONE
  248. // btnClose.visibility = View.GONE
  249. }
  250. }
  251. } else {
  252. if (progressbar.visibility == View.GONE) {
  253. view?.post { progressbar.visibility = View.VISIBLE }
  254. }
  255. }
  256. }
  257. override fun onJsAlert(
  258. view: WebView?,
  259. url: String?,
  260. message: String?,
  261. result: JsResult?
  262. ): Boolean {
  263. val b = AlertDialog.Builder(this@WebActivity)
  264. b.setTitle(message)
  265. b.setPositiveButton("确定") { _, _ ->
  266. result?.confirm()
  267. }
  268. return true
  269. }
  270. }
  271. WebView.setWebContentsDebuggingEnabled(true) //将 WebViews 配置为可调试状态
  272. webView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
  273. }
  274. override fun initData() {
  275. webView.loadUrl(url)
  276. }
  277. override fun initPresenter(): BasePresenter<*>? {
  278. return null
  279. }
  280. override fun onResume() {
  281. super.onResume()
  282. webView.onResume()
  283. checkVersion()
  284. }
  285. override fun onPause() {
  286. super.onPause()
  287. webView.onPause()
  288. }
  289. override fun onBackPressed() {
  290. if (webView.canGoBack()) {
  291. webView.goBack()
  292. } else {
  293. super.onBackPressed()
  294. }
  295. }
  296. override fun onDestroy() {
  297. super.onDestroy()
  298. webView.apply {
  299. // webViewClient = null
  300. webChromeClient = null
  301. (parent as ViewGroup).removeView(webView)
  302. removeAllViews()
  303. destroy()
  304. }
  305. AllenVersionChecker.getInstance().cancelAllMission()
  306. }
  307. /**
  308. * 调用js方法
  309. */
  310. private fun evaluateJavascript(funName: String, data: String) {
  311. webView.post {
  312. webView.evaluateJavascript("javascript:$funName('$data')") {
  313. Log.d("javascriptCallBack:", it)
  314. //toast(it)
  315. }
  316. }
  317. }
  318. @SuppressLint("SetTextI18n")
  319. override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  320. super.onActivityResult(requestCode, resultCode, data)
  321. if (requestCode == BookActivity.REQ_CODE && resultCode == Activity.RESULT_OK) {
  322. val mKey = data?.getStringExtra("key") ?: ""
  323. val mIdentity = data?.getStringExtra("identity") ?: ""
  324. val obj = JSONObject()
  325. obj.put("key", mKey)
  326. obj.put("identity", mIdentity)
  327. obj.put("name", data?.getStringExtra("name") ?: "")
  328. obj.put("index", data?.getIntExtra("index", 0))
  329. obj.put("type", data?.getIntExtra("type", 1))
  330. evaluateJavascript("onImageUploadSuccess", obj.toString())
  331. }
  332. if (requestCode == NoteActivity.REQ_CODE && resultCode == Activity.RESULT_OK) {
  333. val json = data?.getStringExtra("note_info") ?: ""
  334. evaluateJavascript("onImageUploadSuccess", json)
  335. }
  336. }
  337. }
  338. class YzxJavascriptInterface(var ctx: Activity) {
  339. /**
  340. * 获取电子书的clientId
  341. */
  342. @JavascriptInterface
  343. fun getClientId(): Int = 601
  344. /**
  345. * 跳转到电子书页面
  346. */
  347. @JavascriptInterface
  348. fun bookPage(
  349. title: String,
  350. identity: String,
  351. key: String,
  352. name: String,
  353. index: Int,
  354. type: Int
  355. ) {
  356. BookActivity.active(ctx, title, key, identity, name, index, type)
  357. }
  358. /**
  359. * 跳转到笔记页面
  360. * @param title 展示的title
  361. * @param note_info 笔记得json,新的笔记 传"" ,老的笔记 传 [{"BGid":0,"identity":"fileb","key":"a92511a457cdc444bb274e5dee29c487"}]
  362. * @param can_add_page 是否可以新加纸,1可以,0不可以
  363. */
  364. @JavascriptInterface
  365. fun notePage(
  366. title: String,
  367. note_info: String,
  368. can_add_page: Int = 1
  369. ) {
  370. NoteActivity.active(ctx, title, note_info, can_add_page)
  371. }
  372. /**
  373. * 跳转到笔记页面
  374. * @param title 展示的title
  375. * @param note_info 笔记得json,新的笔记 传"" ,老的笔记 传 [{"BGid":0,"identity":"fileb","key":"a92511a457cdc444bb274e5dee29c487"}]
  376. */
  377. @JavascriptInterface
  378. fun notePage(
  379. title: String,
  380. note_info: String
  381. ) {
  382. NoteActivity.active(ctx, title, note_info, 1)
  383. }
  384. /**
  385. * 提示
  386. */
  387. @JavascriptInterface
  388. fun toast(msg: String) {
  389. ctx.toast("android:$msg")
  390. }
  391. /**
  392. * 检查版本升级
  393. */
  394. @JavascriptInterface
  395. fun mCheckVersion() {
  396. Log.d("mCheckVersion", "mCheckVersion: -------------------->")
  397. val act = ctx as WebActivity
  398. act.checkVersion(true)
  399. }
  400. }