| | |
| | | import android.os.Build |
| | | import android.os.IBinder |
| | | import android.os.PowerManager |
| | | import android.util.Log |
| | | import androidx.core.app.NotificationCompat |
| | | import cn.sinata.xldutils.utils.SPUtils |
| | | import com.sinata.xqmuse.network.entity.VoiceDetail |
| | | import com.sinata.xqmuse.utils.AudioUtils |
| | | import com.sinata.xqmuse.utils.Const |
| | | import com.sinata.xqmuse.utils.event.EmptyEvent |
| | | import com.sinata.xqmuse.utils.event.IntEvent |
| | | import kotlinx.android.synthetic.main.activity_main.* |
| | | import org.greenrobot.eventbus.EventBus |
| | | import org.greenrobot.eventbus.Subscribe |
| | | |
| | | class ThinkAudioService:Service() { |
| | | private var mediaPlayer: MediaPlayer? = null |
| | | class ThinkAudioService:Service(), AudioUtils.OnAudioStatusUpdateListener { |
| | | private var thinkBgPlayer: AudioUtils? = null//冥想背景音播放器 |
| | | private var wakeLock: PowerManager.WakeLock? = null |
| | | private val TAG = "ThinkAudioService" |
| | | |
| | | override fun onCreate() { |
| | | super.onCreate() |
| | | EventBus.getDefault().register(this) |
| | | Log.e(TAG,"ThinkAudioService初始化") |
| | | // 初始化 MediaPlayer |
| | | // mediaPlayer = MediaPlayer.create(this, R.raw.audio_sample) |
| | | mediaPlayer!!.isLooping = true |
| | | if (thinkBgPlayer == null){ |
| | | thinkBgPlayer = AudioUtils() |
| | | thinkBgPlayer!!.setOnAudioStatusUpdateListener(this) |
| | | } |
| | | |
| | | // 初始化 WakeLock |
| | | val powerManager = getSystemService(POWER_SERVICE) as PowerManager |
| | |
| | | private val focusChangeListener = |
| | | AudioManager.OnAudioFocusChangeListener { focusChange -> |
| | | if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { |
| | | mediaPlayer!!.pause() // 焦点丢失时暂停播放 |
| | | thinkBgPlayer?.pause() // 焦点丢失时暂停播放 |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | // 启动前台服务 |
| | | val notification = NotificationCompat.Builder(this, "audio_channel") |
| | | .setContentTitle("音频播放中") |
| | | .setContentTitle("正在疗愈") |
| | | .setSmallIcon(R.mipmap.ic_launcher) |
| | | .build() |
| | | startForeground(1, notification) |
| | | |
| | | // 请求音频焦点 |
| | | val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager |
| | | val result = audioManager.requestAudioFocus( |
| | | focusChangeListener, |
| | | AudioManager.STREAM_MUSIC, |
| | | AudioManager.AUDIOFOCUS_GAIN |
| | | ) |
| | | if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { |
| | | mediaPlayer?.start() |
| | | wakeLock?.acquire(30 * 60 * 1000L) // 申请 WakeLock |
| | | } |
| | | // 请求音频焦点 todo 请求焦点会导致首页水波纹视频暂停 |
| | | // val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager |
| | | // val result = audioManager.requestAudioFocus( |
| | | // focusChangeListener, |
| | | // AudioManager.STREAM_MUSIC, |
| | | // AudioManager.AUDIOFOCUS_GAIN |
| | | // ) |
| | | // if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { |
| | | val volume = SPUtils.instance().getInt(Const.User.VOLUME_THINK, 50) |
| | | thinkBgPlayer?.setVolume(volume.toFloat() / 100) |
| | | thinkBgPlayer?.startPlayMusic(this, voice?.meditationMusicList?.get(index)) |
| | | wakeLock?.acquire(60 * 60 * 1000L) // 申请 WakeLock |
| | | // } |
| | | return START_STICKY |
| | | } |
| | | |
| | | override fun onDestroy() { |
| | | if (mediaPlayer != null) { |
| | | mediaPlayer!!.release() |
| | | mediaPlayer = null |
| | | @Subscribe |
| | | fun onAudioEvent(e: EmptyEvent){ |
| | | when(e.code){ |
| | | Const.EventCode.SERVICE_AUDIO_PAUSE->{ |
| | | thinkBgPlayer?.pause() |
| | | } |
| | | Const.EventCode.SERVICE_AUDIO_RESUME->{ |
| | | thinkBgPlayer?.resume() |
| | | } |
| | | Const.EventCode.CHANGE_THINK_VOLUME->{ |
| | | val v = SPUtils.instance().getInt(Const.User.VOLUME_THINK, 50) |
| | | thinkBgPlayer?.setVolume(v.toFloat() / 100) |
| | | } |
| | | Const.EventCode.SERVICE_AUDIO_PROGRESS->{ |
| | | currentPosition = thinkBgPlayer?.currentPosition ?: 0 |
| | | EventBus.getDefault().post(EmptyEvent(Const.EventCode.GOT_THINK_POSITION)) |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Subscribe |
| | | fun onIntEvent(e: IntEvent){ |
| | | if (e.code == Const.EventCode.SERVICE_AUDIO_SEEK){ |
| | | thinkBgPlayer?.seekTo(e.i) |
| | | } |
| | | } |
| | | |
| | | override fun onDestroy() { |
| | | EventBus.getDefault().unregister(this) |
| | | thinkBgPlayer?.stopPlayMusic(false) |
| | | if (wakeLock != null && wakeLock!!.isHeld) { |
| | | wakeLock!!.release() |
| | | } |
| | | super.onDestroy() |
| | | } |
| | | |
| | | override fun onUpdate(db: Double, time: Long) { |
| | | |
| | | } |
| | | |
| | | override fun onStop(filePath: String?) { |
| | | } |
| | | |
| | | override fun onStartPlay() { |
| | | } |
| | | |
| | | 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) { |
| | | } |
| | | |
| | | 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 //自动结束的时间戳 |
| | | } |
| | | } |