| | |
| | | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | |
| | | 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 |
| | |
| | | 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 { |
| | |
| | | } |
| | | |
| | | 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() |
| | |
| | | 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) |
| | | if (System.currentTimeMillis() - startTime >= 60000){ |
| | | saveThinkRecord() |
| | | } |
| | | } |
| | | 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() |
| | |
| | | */ |
| | | 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() //记录开始冥想的时间 |
| | |
| | | */ |
| | | 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() //对比当前音频是否是每日疗愈 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 申请浮窗权限 增加稳定性 |
| | | */ |
| | | 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, { _, _ -> |
| | | startTime = System.currentTimeMillis() |
| | | HttpManager.saveViewingHistory(ThinkAudioService.voice?.id ?: "", time).request(this, false, { _, _ -> |
| | | Log.e(Const.Tag, "冥想记录成功:$time 秒") |
| | | }){ _, _-> |
| | | Log.e(Const.Tag, "冥想记录失败:$time 秒") |
| | |
| | | } |
| | | |
| | | override fun onTabSelect(position: Int) { |
| | | if (position == 4 && SPUtils.instance().getString(Const.User.TOKEN).isNullOrEmpty()){ |
| | | toast("请先登录") |
| | | startActivity<LoginActivity>() |
| | | tab_bar.currentTab = 0 |
| | | return |
| | | if (position == 4 ){ |
| | | if (SPUtils.instance().getString(Const.User.TOKEN).isNullOrEmpty()){ |
| | | toast("请先登录") |
| | | startActivity<LoginActivity>() |
| | | tab_bar.currentTab = 0 |
| | | return |
| | | }else |
| | | (fragments[4] as MineFragment).showUserInfo() |
| | | } |
| | | |
| | | view_pager.currentItem = position |
| | | if (position == 2){ |
| | | (fragments[2] as TreeFragment).getTree() |
| | |
| | | cl_player.alpha = 1f |
| | | } |
| | | } |
| | | if (position == 1){ |
| | | (fragments[1] as CourseFragment).refreshDataByResume() |
| | | } |
| | | if (position == 4){ |
| | | (fragments[4] as MineFragment).queryUnread() |
| | | } |
| | | if (position != 1) |
| | | EventBus.getDefault().post(EmptyEvent(Const.EventCode.PAUSE_TEACHER_VIDEO)) |
| | | if (position == 0) |
| | | if (position == 0){ |
| | | (fragments[0] as HomeFragment).refreshDataByResume() |
| | | startTodayCheck() |
| | | } |
| | | else |
| | | stopTodayCheck() |
| | | } |
| | |
| | | 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 //正在播放疗愈,无法立即切换背景音乐 |
| | |
| | | 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() |
| | |
| | | @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() |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | 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) |
| | |
| | | super.onResume() |
| | | if (view_pager.currentItem == 4){ |
| | | (fragments[4] as MineFragment).queryUnread() |
| | | (fragments[4] as MineFragment).showUserInfo() |
| | | } else if (view_pager.currentItem == 0){ |
| | | startTodayCheck() |
| | | (fragments[0] as HomeFragment).refreshDataByResume() |
| | | } else if (view_pager.currentItem == 2){ |
| | | (fragments[2] as TreeFragment).getTree() |
| | | } else if (view_pager.currentItem == 1){ |
| | | (fragments[1] as CourseFragment).refreshDataByResume() |
| | | } |
| | | if (isFirst&&!hasTreeFirstShow&&!SPUtils.instance().getString(Const.User.ANSWER).isNullOrEmpty()){ //如果是第一次安装并且还没显示树苗打卡引导并且答完题了 就去树苗引导 |
| | | tab_bar.currentTab = 2 |
| | |
| | | } |
| | | |
| | | 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) { |
| | |
| | | override fun onBackPressed() { |
| | | if (teacherVideoView?.onBackPressed() != true) |
| | | 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 //自动结束的时间戳 |
| | | } |
| | | } |