From 449bdb5d2b5bf7b272ca5cda4c066f9a65040064 Mon Sep 17 00:00:00 2001
From: lmw <125975490@qq.com>
Date: 星期二, 04 三月 2025 14:30:40 +0800
Subject: [PATCH] fix

---
 app/src/main/java/com/sinata/xqmuse/MainActivity.kt |  173 +++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 105 insertions(+), 68 deletions(-)

diff --git a/app/src/main/java/com/sinata/xqmuse/MainActivity.kt b/app/src/main/java/com/sinata/xqmuse/MainActivity.kt
index c2fb678..0c67e6f 100644
--- a/app/src/main/java/com/sinata/xqmuse/MainActivity.kt
+++ b/app/src/main/java/com/sinata/xqmuse/MainActivity.kt
@@ -2,13 +2,12 @@
 
 import android.annotation.SuppressLint
 import android.content.Intent
-import android.os.Handler
-import android.os.Looper
-import android.os.Message
+import android.net.Uri
+import android.os.*
 import android.provider.Settings
 import android.util.Log
+import android.view.Gravity
 import android.view.View
-import android.view.WindowManager
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.FragmentPagerAdapter
 import cn.sinata.xldutils.gone
@@ -17,6 +16,10 @@
 import com.flyco.tablayout.listener.CustomTabEntity
 import com.flyco.tablayout.listener.OnTabSelectListener
 import com.google.gson.Gson
+import com.lzf.easyfloat.EasyFloat
+import com.lzf.easyfloat.enums.ShowPattern
+import com.lzf.easyfloat.enums.SidePattern
+import com.lzf.easyfloat.interfaces.OnInvokeView
 import com.sinata.xqmuse.dialog.TipDialog
 import com.sinata.xqmuse.network.HttpManager
 import com.sinata.xqmuse.network.entity.VoiceDetail
@@ -35,12 +38,14 @@
 import com.sinata.xqmuse.utils.Const
 import com.sinata.xqmuse.utils.event.EmptyEvent
 import com.sinata.xqmuse.utils.event.IntEvent
+import com.umeng.socialize.utils.DeviceConfigInternal.context
 import kotlinx.android.synthetic.main.activity_main.*
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.jetbrains.anko.startActivity
 import org.jetbrains.anko.toast
 import xyz.doikki.videoplayer.player.VideoView
+
 
 class MainActivity : TransparentStatusBarActivity(), OnTabSelectListener,AudioUtils.OnAudioStatusUpdateListener {
     override fun setContentView() = R.layout.activity_main
@@ -49,7 +54,7 @@
 
     var teacherVideoView:VideoView? = null
     private var bgPlayer:AudioUtils? = null//背景音乐播放器
-    private var thinkBgPlayer:AudioUtils? = null//冥想背景音播放器
+//    private var thinkBgPlayer:AudioUtils? = null//冥想背景音播放器
 //    private var thinkPlayer:AudioUtils? = null//冥想背景音播放器
 
     private var guideAudio:String? = null
@@ -71,6 +76,9 @@
     var hasTreeFirstShow = false //此字段用来判断 树苗的首次弹窗是否已经触发,和isFirst字段配合使用
     var isBGMChanged = false //此字段用来判断 在疗愈播放中,修改了背景音乐,在疗愈结束后 需要更新BGM音源
 
+    private val EasyFloatTag = "BACKGROUND"
+    private var floater: EasyFloat.Builder? = null //浮窗
+
     override fun initClick() {
         player_close.setOnClickListener {
             TipDialog.show(supportFragmentManager, "是否关闭当前音频?", object : TipDialog.OnClickCallback {
@@ -84,20 +92,24 @@
         }
 
         cl_player.setOnClickListener {
-            voice?.goDetail(this)
+            ThinkAudioService.voice?.goDetail(this)
         }
 
         player_play.setOnClickListener {
-            playing = !playing
-            if (playing){
+            ThinkAudioService.playing = !ThinkAudioService.playing
+            if (ThinkAudioService.playing){
                 player_play.setImageResource(R.mipmap.player_pause)
-                thinkBgPlayer?.resume()
+                EventBus.getDefault().post(EmptyEvent(Const.EventCode.USER_INFO_CHANGED))
+                EventBus.getDefault().post(EmptyEvent(Const.EventCode.SERVICE_AUDIO_RESUME))
+//                thinkBgPlayer?.resume()
 //                thinkPlayer?.resume()
                 thinkHandler?.sendEmptyMessage(MSG_PROGRESS)
                 startTime = System.currentTimeMillis()
             }else{
                 player_play.setImageResource(R.mipmap.player_start)
-                thinkBgPlayer?.pause()
+                EventBus.getDefault().post(EmptyEvent(Const.EventCode.USER_INFO_CHANGED))
+                EventBus.getDefault().post(EmptyEvent(Const.EventCode.SERVICE_AUDIO_PAUSE))
+//                thinkBgPlayer?.pause()
 //                thinkPlayer?.pause()
                 thinkHandler?.removeMessages(MSG_PROGRESS)
                 saveThinkRecord()
@@ -123,17 +135,16 @@
                 super.handleMessage(msg)
                 when(msg.what){
                     MSG_PROGRESS -> {
-                        currentPosition = thinkBgPlayer?.currentPosition ?: 0
-                        EventBus.getDefault().post(EmptyEvent(Const.EventCode.GOT_THINK_POSITION))
+                        EventBus.getDefault().post(EmptyEvent(Const.EventCode.SERVICE_AUDIO_PROGRESS))
                         sendEmptyMessageDelayed(MSG_PROGRESS, 1000)
                     }
                     MSG_COUNTDOWN -> {
-                        if (System.currentTimeMillis() >= finishTime)
+                        if (System.currentTimeMillis() >= ThinkAudioService.finishTime)
                             EventBus.getDefault().post(EmptyEvent(Const.EventCode.FINISH_THINK))
                         else
                             sendEmptyMessageDelayed(MSG_COUNTDOWN, 1000)
                     }
-                    MSG_TODAY -> {
+                    MSG_TODAY -> { //todo 分离hanlder,这个保持原功能,进度和计时相关应放进Service
                         if (System.currentTimeMillis() - lastTodayTime > 60000) { //距离上次刷新过去了1分钟
                             Log.e(Const.Tag, "已经过1分钟,需要重新获取今日疗愈数据")
                             lastTodayTime = System.currentTimeMillis()
@@ -183,21 +194,22 @@
      */
     private fun startThink() {
         bgPlayer?.pause()
-        index = 0
-        if (voice?.meditationMusicList?.isNullOrEmpty() == false){
-            if (thinkBgPlayer == null){
-                thinkBgPlayer = AudioUtils()
-                thinkBgPlayer!!.setOnAudioStatusUpdateListener(this)
+        ThinkAudioService.index = 0
+        if (ThinkAudioService.voice?.meditationMusicList?.isNullOrEmpty() == false){
+            checkFloat() //检测浮窗
+            // 启动音乐服务
+            val serviceIntent = Intent(this, ThinkAudioService::class.java)
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                startForegroundService(serviceIntent)
+            } else {
+                startService(serviceIntent)
             }
-            val volume = SPUtils.instance().getInt(Const.User.VOLUME_THINK, 50)
-            thinkBgPlayer?.setVolume(volume.toFloat() / 100)
-            thinkBgPlayer?.startPlayMusic(this, voice?.meditationMusicList?.get(index))
-            currentDuration = voice?.meditationSecondList?.get(index)?:0
+            ThinkAudioService.currentDuration = ThinkAudioService.voice?.meditationSecondList?.get(ThinkAudioService.index)?:0
             EventBus.getDefault().post(EmptyEvent(Const.EventCode.GOT_THINK_DURATION))
-            playing = true
+            ThinkAudioService.playing = true
             cl_player.visible()
-            tv_player.text = voice?.meditationTitle
-            iv_player.setImageURI(voice?.coverUrl?.split(",")?.firstOrNull())
+            tv_player.text = ThinkAudioService.voice?.meditationTitle
+            iv_player.setImageURI(ThinkAudioService.voice?.coverUrl?.split(",")?.firstOrNull())
             player_play.setImageResource(R.mipmap.player_pause)
             thinkHandler?.sendEmptyMessage(MSG_PROGRESS)
             startTime = System.currentTimeMillis()  //记录开始冥想的时间
@@ -210,11 +222,12 @@
      */
     private fun finishThink(){
         saveThinkRecord()
-        voice = null
-        index = 0
-        finishTime = 0L
-        thinkBgPlayer?.stopPlayMusic(true)
-        playing = false
+        ThinkAudioService.voice = null
+        ThinkAudioService.index = 0
+        ThinkAudioService.finishTime = 0L
+        // 停止服务
+        stopService(Intent(this, ThinkAudioService::class.java))
+        ThinkAudioService.playing = false
         thinkHandler?.removeMessages(0)
         cl_player.gone()
         (fragments[0] as HomeFragment).refreshTodayPlayingState() //对比当前音频是否是每日疗愈
@@ -227,14 +240,41 @@
     }
 
     /**
+     * 申请浮窗权限 增加稳定性
+     */
+    private fun checkFloat() {
+        if (!Settings.canDrawOverlays(this) && SPUtils.instance().getString("isRefusedFloat").isNullOrEmpty()) { //没有浮窗权限并且没有拒绝过
+            TipDialog.show(
+                supportFragmentManager,
+                "为了增加后台播放的稳定性,我们需要开启悬浮窗口权限",
+                object : TipDialog.OnClickCallback {
+                    override fun onOk() {
+                        var intent = Intent(
+                            Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
+                            Uri.parse("package:" + packageName)
+                        )
+                        startActivityForResult(intent, 1234)
+                    }
+
+                    override fun onCancel() {
+                    }
+                },
+                "去开启",
+                "取消"
+            )
+        }
+    }
+
+
+    /**
      * 保存冥想记录
      */
     private fun saveThinkRecord() {
-        if (voice == null||startTime == 0L||SPUtils.instance().getString(Const.User.TOKEN).isNullOrEmpty())
+        if (ThinkAudioService.voice == null||startTime == 0L||SPUtils.instance().getString(Const.User.TOKEN).isNullOrEmpty())
             return
         val time = ((System.currentTimeMillis() - startTime) / 1000).toInt()
         startTime = 0L
-        HttpManager.saveViewingHistory(voice?.id ?: "", time).request(this, false, { _, _ ->
+        HttpManager.saveViewingHistory(ThinkAudioService.voice?.id ?: "", time).request(this, false, { _, _ ->
             Log.e(Const.Tag, "冥想记录成功:$time 秒")
         }){ _, _->
             Log.e(Const.Tag, "冥想记录失败:$time 秒")
@@ -344,12 +384,17 @@
             tab_bar.currentTab = 3
             onTabSelect(3)
         }else if(e.code == Const.EventCode.APP_FOREGROUND){
-            if (voice==null)
+            EasyFloat.hide(EasyFloatTag)
+            if (ThinkAudioService.voice==null)
                 bgPlayer?.resume()
         }else if(e.code == Const.EventCode.APP_BACKGROUND){
             bgPlayer?.pause()
+            if ( ThinkAudioService.playing && Settings.canDrawOverlays(this) ) {
+                showFloater()
+                EasyFloat.show(EasyFloatTag)
+            }
         }else if(e.code == Const.EventCode.CHANGE_BGM){
-            if (voice == null)
+            if (ThinkAudioService.voice == null)
                 startBgm()
             else
                 isBGMChanged = true //正在播放疗愈,无法立即切换背景音乐
@@ -359,21 +404,18 @@
             finishThink()
         }else if(e.code == Const.EventCode.PAUSE_OR_RESUME_THINK){
             player_play.callOnClick()
-        }else if(e.code == Const.EventCode.CHANGE_THINK_VOLUME){
-            val v = SPUtils.instance().getInt(Const.User.VOLUME_THINK, 50)
-            thinkBgPlayer?.setVolume(v.toFloat() / 100)
         }else if(e.code == Const.EventCode.START_GUIDE_AUDIO){
             inGuide = true
             startGuide()
             bgPlayer?.pause()
-            thinkBgPlayer?.pause()
+            EventBus.getDefault().post(EmptyEvent(Const.EventCode.SERVICE_AUDIO_PAUSE))
         }else if(e.code == Const.EventCode.FINISH_GUIDE_AUDIO){
             inGuide = false
             guidePlayer?.stopPlayMusic(false)
-            if (voice!=null&& playing){
-                thinkBgPlayer?.resume()
+            if (ThinkAudioService.voice!=null&& ThinkAudioService.playing){
+                EventBus.getDefault().post(EmptyEvent(Const.EventCode.SERVICE_AUDIO_RESUME))
             }
-            if (voice == null)
+            if (ThinkAudioService.voice == null)
                 bgPlayer?.resume()
         }else if(e.code == Const.EventCode.REFRESH_PRIVATE){ //重新答题后,刷新私人定制
             (fragments[0] as HomeFragment).getPrivacy()
@@ -385,7 +427,7 @@
     @Subscribe
     fun onIntEvent(e: IntEvent){
         if (e.code == Const.EventCode.THINK_SEEK_PROGRESS){
-            thinkBgPlayer?.seekTo(e.i)
+            EventBus.getDefault().post(IntEvent(Const.EventCode.SERVICE_AUDIO_SEEK,e.i))
             player_play.callOnClick()
         }
     }
@@ -408,6 +450,25 @@
         }
     }
 
+    private fun showFloater() {
+        if (floater == null){
+            floater = EasyFloat.with(applicationContext)
+                .setLayout(R.layout.layout_floter, OnInvokeView {
+                })
+                .setShowPattern(ShowPattern.ALL_TIME)
+                .setSidePattern(SidePattern.RESULT_LEFT)
+                .setGravity(Gravity.START or Gravity.BOTTOM, 0, 0)
+                .setDragEnable(true)
+                .setTag(EasyFloatTag)
+                .setMatchParent(widthMatch = false, heightMatch = false)
+                .registerCallback {
+                    touchEvent { view, motionEvent ->
+                        motionEvent.action
+                    }
+                }
+            floater?.show()
+        }
+    }
 
     private fun startTodayCheck(){
         thinkHandler?.sendEmptyMessage(MSG_TODAY)
@@ -460,22 +521,7 @@
     }
 
     override fun onFinishPlay() {
-        if (voice == null) //说明是手动关闭的,不需要处理下一步播放逻辑
-            return
-        if (isRecycle){ //单曲
-            if (playing)
-                thinkBgPlayer?.startPlayMusic(this, voice?.meditationMusicList?.get(index))
-        }else{//顺序
-            index++
-            if (index>=voice?.meditationMusicList?.size?:0)//列表已播完
-                EventBus.getDefault().post(EmptyEvent(Const.EventCode.FINISH_THINK))
-            else{
-                currentDuration = voice?.meditationSecondList?.get(index)?:0
-                EventBus.getDefault().post(EmptyEvent(Const.EventCode.GOT_THINK_DURATION))
-                if (playing)
-                    thinkBgPlayer?.startPlayMusic(this, voice?.meditationMusicList?.get(index))
-            }
-        }
+
     }
 
     override fun onGetDuration(duration: Int) {
@@ -487,13 +533,4 @@
             super.onBackPressed()
     }
 
-    companion object{ //冥想播放相关参数
-        var playing = false //true播放中
-        var isRecycle = false //true单曲循环播放
-        var voice: VoiceDetail? = null //冥想详情
-        var index = 0 //当前播放序号
-        var currentDuration = 0 //当前音频长度(秒)
-        var currentPosition = 0L //当前音频进度(毫秒)
-        var finishTime = 0L //自动结束的时间戳
-    }
 }
\ No newline at end of file

--
Gitblit v1.7.1