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