123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- package com.dlc.exam.ui.learn
- import android.annotation.SuppressLint
- import android.content.Intent
- import android.graphics.Bitmap
- import android.os.Build
- import android.os.Bundle
- import android.os.Handler
- import android.os.Looper
- import android.os.Message
- import android.util.Log
- import android.view.LayoutInflater
- import android.view.View
- import android.view.ViewGroup
- import android.webkit.ConsoleMessage
- import android.webkit.WebChromeClient
- import android.webkit.WebResourceError
- import android.webkit.WebResourceRequest
- import android.webkit.WebSettings
- import android.webkit.WebView
- import android.webkit.WebViewClient
- import android.widget.LinearLayout
- import androidx.annotation.RequiresApi
- import com.blankj.utilcode.util.LogUtils
- import com.bumptech.glide.Glide
- import com.dlc.exam.R
- import com.dlc.exam.common.CommonUtils
- import com.dlc.exam.databinding.ActivityLearnDetailBinding
- import com.dlc.exam.ui.common.BaseCountDownActivity
- import com.dlc.exam.ui.learn.test.ClassTestActivity
- import com.google.android.exoplayer2.ExoPlayer
- import com.google.android.exoplayer2.MediaItem
- import com.rc.core.log.RcLog
- import com.rc.core.util.EscapeUnescape
- import com.rc.httpcore.HttpConfig
- import com.rc.httpcore.client.ApiRepository
- import com.rc.httpcore.vo.request.ExamLearnReq
- /**
- * 学习详情
- *
- * @author ReiChin_
- */
- class LearnDetailActivity : BaseCountDownActivity<ActivityLearnDetailBinding>() {
- override fun createViewBinding() = ActivityLearnDetailBinding.inflate(LayoutInflater.from(this))
- private var mNextChapterList: ArrayList<LearnChapterBean>? = null
- private var mCurrentPosition = 0
- private lateinit var mCurrentChapter: LearnChapterBean
- private var mLearnCompleted = false
- private var mLearnTimeSecond = 0L
- private var mRelearn = false
- private var mVideoDraggable = false // 视频是否可以拖拽
- private var mAssessStatus = false // 是否需要课后考核
- private var exoPlayer: ExoPlayer? = null
- private var webView: WebView? = null
- private val indexUrl = "file:///android_asset/web/index.html"
- companion object {
- const val WHAT_LEARN_COUNT_DOWN = 1
- }
- override fun onResume() {
- super.onResume()
- exoPlayer?.play()
- }
- override fun initViews(savedInstanceState: Bundle?) {
- super.initViews(savedInstanceState)
- mNextChapterList = intent.getParcelableArrayListExtra("nextChapter")
- if (mNextChapterList.isNullOrEmpty()) {
- finish()
- return
- }
- mRelearn = intent.getBooleanExtra("relearn", false)
- mVideoDraggable = intent.getBooleanExtra("videoDraggable", false)
- mAssessStatus = intent.getBooleanExtra("assessStatus", false)
- exoPlayer = ExoPlayer.Builder(this).build()
- viewBinding.styledPlayerView.player = exoPlayer
- viewBinding.styledPlayerView.useController = false
- viewBinding.back.setOnClickListener { onBackPressed() }
- viewBinding.learnCompleted.visibility = if (mRelearn) View.GONE else View.VISIBLE
- viewBinding.learnCompleted.setOnClickListener {
- mLearnTimeSecond = 0L
- mLearnCountDownHandler.removeMessages(WHAT_LEARN_COUNT_DOWN)
- // 完成学习
- callFinishLearnApi()
- }
- initWebView()
- //TODO 等待webview初始化完毕后调用
- // showChapterInfo()
- }
- private fun initWebView() {
- val params = LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT
- )
- webView = WebView(applicationContext)
- webView?.layoutParams = params
- viewBinding.mainLL.addView(webView)
- WebView.setWebContentsDebuggingEnabled(true)
- val webSettings: WebSettings? = webView?.getSettings()
- webSettings?.javaScriptCanOpenWindowsAutomatically = true
- webSettings?.setSupportZoom(true)
- webSettings?.loadWithOverviewMode = true
- webSettings?.useWideViewPort = true
- webSettings?.domStorageEnabled = true //DOM Storage
- webSettings?.allowFileAccessFromFileURLs = true
- webSettings?.allowFileAccess = true
- webSettings?.allowContentAccess = true
- webSettings?.allowUniversalAccessFromFileURLs = true
- webSettings?.builtInZoomControls = true
- webSettings?.defaultTextEncodingName = "utf-8"
- webSettings?.javaScriptEnabled = true //设置webview支持javascript脚本
- webSettings?.mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE
- webView!!.webChromeClient = object : WebChromeClient() {
- override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
- if (ConsoleMessage.MessageLevel.ERROR == consoleMessage.messageLevel()) {
- LogUtils.e(
- "Jayce",
- "${consoleMessage.message()}+\n+${consoleMessage.lineNumber()}+\n+${consoleMessage.sourceId()}"
- )
- // pptxjs.js 该库异常会奔溃
- if (consoleMessage.sourceId().contains("pptxjs.js")) {
- showToast("该ppt不可用")
- this@LearnDetailActivity.finish()
- }
- } else {
- LogUtils.d(
- "Jayce",
- "${consoleMessage.message()}+\n+${consoleMessage.lineNumber()}+\n+${consoleMessage.sourceId()}"
- )
- }
- return true
- }
- override fun onProgressChanged(view: WebView, newProgress: Int) {
- super.onProgressChanged(view, newProgress)
- Log.d("Jayce", "p:$newProgress")
- }
- override fun onCloseWindow(window: WebView) {
- super.onCloseWindow(window)
- val js = "javascript:objPreviewerDestroy()"
- webView!!.evaluateJavascript(
- js
- ) { value -> }
- }
- }
- webView!!.webViewClient = object : WebViewClient() {
- /**
- * 页面开始加载
- * @param view The WebView that is initiating the callback.
- * @param url The url to be loaded.
- * @param favicon The favicon for this page if it already exists in the
- * database.
- */
- override fun onPageStarted(view: WebView, url: String, favicon: Bitmap) {
- super.onPageStarted(view, url, favicon)
- }
- /**
- * 页面加载完成
- * @param view The WebView that is initiating the callback.
- * @param url The url of the page.
- */
- override fun onPageFinished(view: WebView, url: String) {
- super.onPageFinished(view, url)
- // 等页面初始化完成后再去请求接口展示详情
- runOnUiThread {
- showChapterInfo()
- }
- }
- /**
- * 页面加载错误
- * @param view The WebView that is initiating the callback.
- * @param request The originating request.
- * @param error Information about the error occurred.
- */
- @RequiresApi(Build.VERSION_CODES.M)
- override fun onReceivedError(
- view: WebView,
- request: WebResourceRequest,
- error: WebResourceError
- ) {
- super.onReceivedError(view, request, error)
- Log.d(
- "Jayce",
- "${error.description}"
- )
- }
- }
- webView!!.requestFocus()
- webView!!.loadUrl(indexUrl)
- }
- private fun callFinishLearnApi() {
- showLoading("保存中...")
- val param = ExamLearnReq().apply {
- chapterId = mCurrentChapter.chapterId
- courseId = mCurrentChapter.courseId
- }
- val disposable = ApiRepository.examLearnFinish(param)
- .subscribe({ data ->
- dismissLoading()
- mLearnCompleted = true
- // 显示完成学习的Dialog
- val endChapter = mCurrentPosition == mNextChapterList!!.size - 1
- LearnCompletedDialog(this, data, endChapter, mCurrentChapter.assessStatus) {
- viewBinding.learnCompleted.isEnabled = false
- if (mCurrentChapter.assessStatus) {
- // 需要课后考核
- val intent = Intent(this, ClassTestActivity::class.java)
- intent.putExtra("chapterId", mCurrentChapter.chapterId)
- startActivity(intent)
- setResult(RESULT_OK)
- finish()
- } else {
- mCurrentPosition++
- showChapterInfo()
- }
- }.show()
- }, { throwable ->
- dismissLoading()
- throwable.printStackTrace()
- showNetError(throwable)
- })
- addDisposable(disposable)
- }
- @SuppressLint("SetTextI18n")
- private fun showChapterInfo() {
- Log.d("Jayce", "showChapterInfo")
- if (mCurrentPosition >= mNextChapterList!!.size) return
- mCurrentChapter = mNextChapterList!![mCurrentPosition]
- viewBinding.titleText.text = mCurrentChapter.title
- // 显示学习内容
- showLearnContent()
- if (mRelearn) {
- viewBinding.learnDuration.text =
- "已学习时长:${CommonUtils.formatLearnTime(mCurrentChapter.duration)}"
- } else {
- // 调用开始学习的API
- callStartLearnApi()
- }
- }
- // var str =
- // "http://192.168.251.2//labSystem//statics//bigFile//2023040314//2c7593c7-c6ba-4bf2-9dab-da7db456494e.mp4"
- var str =
- "https://vd4.bdstatic.com/mda-kfmi6042m94u0pdb/sc/mda-kfmi6042m94u0pdb.mp4"
- private fun showLearnContent() {
- when (mCurrentChapter.type) {
- "1" -> {
- // 文档
- webView?.visibility = View.VISIBLE
- viewBinding.progressbar.visibility = View.VISIBLE
- viewBinding.unknownFile.visibility = View.INVISIBLE
- viewBinding.imageContent.visibility = View.INVISIBLE
- viewBinding.styledPlayerView.visibility = View.INVISIBLE
- var url = if (mCurrentChapter.chapterData.startsWith("http")) {
- mCurrentChapter.chapterData
- } else {
- HttpConfig.API_BASE_URL + mCurrentChapter.chapterData
- }
- // RcLog.info("fileBrowsers_s:${s}")
- // val infoData =
- //// Base64.encodeToString(mCurrentChapter.chapterData.toByteArray(), Base64.DEFAULT)
- // Base64.encodeToString(s.toByteArray(), Base64.DEFAULT)
- // val baseurl = "${HttpConfig.FILE_BROWSER_BASE_URL}onlinePreview?url=$infoData"
- // RcLog.info("fileBrowser:${baseurl}")
- var function = ""
- var loadUrl = ""
- // ppt
- if (url.endsWith(".ppt") || url.endsWith(".pptx")) {
- function = "openPPT"
- loadUrl = "http://192.168.1.43:81/666/ppt.pptx"
- }
- // excel
- else if (url.endsWith(".xlsx") || url.endsWith(".xls")) {
- function = "openEXCEL"
- loadUrl = "http://192.168.1.43:81/666/excel.xlsx"
- }
- // word
- else if (url.endsWith(".docx") || url.endsWith(".doc")) {
- function = "openWORD"
- loadUrl = "http://192.168.1.43:81/666/word.docx"
- } else if (url.endsWith(".pdf")) {
- function = "openPDF"
- loadUrl = "http://192.168.1.43:81/666/pdf.pdf"
- } else {
- showToast("不支持的文件")
- this.finish()
- return
- }
- val js = "javascript:$function(\"$loadUrl\")"
- webView!!.evaluateJavascript(js) { value -> }
- // webView?.loadUrl(url)
- }
- "2" -> {
- // 视频 VISIBLE
- webView?.visibility = View.GONE
- viewBinding.progressbar.visibility = View.GONE
- viewBinding.unknownFile.visibility = View.GONE
- viewBinding.imageContent.visibility = View.GONE
- viewBinding.styledPlayerView.visibility = View.VISIBLE
- var url = if (mCurrentChapter.chapterData.startsWith("http")) {
- mCurrentChapter.chapterData
- // viewBinding.jzVideo.setUp(mCurrentChapter.chapterData, mCurrentChapter.title)
- } else {
- HttpConfig.API_BASE_URL + mCurrentChapter.chapterData
- // viewBinding.jzVideo.setUp(HttpConfig.API_BASE_URL + mCurrentChapter.chapterData,
- // mCurrentChapter.title)
- }
- // showToast("视频地址:" + HttpConfig.API_BASE_URL + mCurrentChapter.chapterData)
- val mediaItem = MediaItem.fromUri(url)
- exoPlayer?.let {
- it.setMediaItem(mediaItem)
- it.prepare()
- it.play()
- }
- // viewBinding.webView.loadUrl(str)
- // viewBinding.webView.loadUrl(mCurrentChapter.chapterData)
- // 这个对宿主没什么影响,建议声明
- // window.setFormat(PixelFormat.TRANSLUCENT)
- // viewBinding.webView.settings.mediaPlaybackRequiresUserGesture = false //设置自动播放
- // viewBinding.webView.overScrollMode = View.OVER_SCROLL_ALWAYS
- // //TODO 饺子播放器在内网环境 不可使用 加载缓慢
- // val bundle = Bundle()
- // bundle.putBoolean("standardFullScreen", false)
- // bundle.putBoolean("supportLiteWnd", true)
- // bundle.putInt("DefaultVideoScreen", 1)
- //// TbsVideo.openVideo(this, str, bundle)
- // TbsVideo.openVideo(this, url, bundle)
- }
- "3" -> {
- // 图片
- webView?.visibility = View.INVISIBLE
- viewBinding.progressbar.visibility = View.INVISIBLE
- viewBinding.unknownFile.visibility = View.INVISIBLE
- viewBinding.imageContent.visibility = View.VISIBLE
- viewBinding.styledPlayerView.visibility = View.INVISIBLE
- // var s = if (mCurrentChapter.chapterData.startsWith("http")) {
- // mCurrentChapter.chapterData
- // } else {
- // mCurrentChapter.chapterData
- // }
- Glide.with(this)
- .load(mCurrentChapter.chapterData)
- .placeholder(R.mipmap.img_bg_jzz)
- .error(R.mipmap.img_error)
- .into(viewBinding.imageContent)
- }
- "5" -> {
- // 富文本
- webView?.visibility = View.VISIBLE
- viewBinding.progressbar.visibility = View.VISIBLE
- viewBinding.unknownFile.visibility = View.INVISIBLE
- viewBinding.imageContent.visibility = View.INVISIBLE
- viewBinding.styledPlayerView.visibility = View.INVISIBLE
- webView?.loadDataWithBaseURL(
- null,
- EscapeUnescape.unescape(mCurrentChapter.chapterData),
- "text/html",
- "utf-8",
- null
- )
- }
- else -> {
- webView?.visibility = View.INVISIBLE
- viewBinding.progressbar.visibility = View.INVISIBLE
- viewBinding.unknownFile.visibility = View.VISIBLE
- viewBinding.imageContent.visibility = View.INVISIBLE
- viewBinding.styledPlayerView.visibility = View.INVISIBLE
- }
- }
- }
- private fun callStartLearnApi() {
- showLoading("加载中...")
- val param = ExamLearnReq().apply {
- chapterId = mCurrentChapter.chapterId
- courseId = mCurrentChapter.courseId
- }
- val disposable = ApiRepository.examLearnStart(param)
- .subscribe({
- dismissLoading()
- // 开始倒计时
- mLearnTimeSecond = 0
- mLearnCountDownHandler.sendEmptyMessage(WHAT_LEARN_COUNT_DOWN)
- }, { throwable ->
- dismissLoading()
- throwable.printStackTrace()
- showNetError(throwable)
- })
- addDisposable(disposable)
- }
- private val mLearnCountDownHandler = object : Handler(Looper.getMainLooper()) {
- @SuppressLint("SetTextI18n")
- override fun handleMessage(msg: Message) {
- mLearnTimeSecond++
- viewBinding.learnDuration.text =
- "已学习时长:${CommonUtils.formatLearnTime(mLearnTimeSecond)}"
- sendEmptyMessageDelayed(WHAT_LEARN_COUNT_DOWN, 1000)
- if (mLearnTimeSecond >= mCurrentChapter.duration) {
- viewBinding.learnCompleted.isEnabled = true
- }
- }
- }
- override fun onWindowFocusChanged(hasFocus: Boolean) {
- super.onWindowFocusChanged(hasFocus)
- if (hasFocus) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
- or View.SYSTEM_UI_FLAG_FULLSCREEN
- or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
- }
- }
- }
- override fun onPause() {
- RcLog.info("onPause=======================================")
- super.onPause()
- exoPlayer?.pause()
- }
- override fun onDestroy() {
- mLearnCountDownHandler.removeMessages(WHAT_LEARN_COUNT_DOWN)
- mLearnCountDownHandler.removeCallbacksAndMessages(null)
- super.onDestroy()
- exoPlayer?.release()
- }
- override fun onBackPressed() {
- RcLog.info("onBackPressed============================")
- if (mLearnCompleted) {
- setResult(RESULT_OK)
- }
- super.onBackPressed()
- }
- }
|