Commit e8c6a1ea by 刘鹏

Merge branch 'd/lancet/4.3.93_muse' into 'd/4.3.93_muse'

D/lancet/4.3.93 muse

See merge request app_android_lib/YDL-Component!52
parents cf83bbfe 674cf978
......@@ -14,7 +14,7 @@ ext {
"m-dynamic" : "0.0.7.73",
"m-article" : "0.0.0.10",
"m-muse" : "0.0.28.39",
"m-muse" : "0.0.28.38",
"m-tests" : "0.0.24.18",
"m-course" : "0.0.43.37",
......@@ -99,7 +99,7 @@ ext {
"m-dynamic" : "0.0.7.73",
"m-article" : "0.0.0.8",
"m-muse" : "0.0.28.39",
"m-muse" : "0.0.28.38",
"m-tests" : "0.0.24.18",
"m-course" : "0.0.43.37",
//-------------- 业务模块 API 层 --------------
......
......@@ -87,87 +87,58 @@ class HomeMuseView(private val mContext: Context, private var homeEvent: IHomeEv
}
iv_video_background?.setOnClickListener {
// homeEvent?.museMoreClick(Gson().toJson(bean))
if (Utils.isFastClick()) {
//防止连击
return@setOnClickListener
}
if (!moreLink.isNullOrBlank()) {
NewH5Activity.start(context, H5Params(moreLink, null))
}
}
val greeting = bean.mditationIndexInfo?.greetings?:"你好"
val greeting = bean.mditationIndexInfo?.greetings ?: "你好"
tv_time.text = greeting
val slogan =
if (bean.mditationIndexInfo?.desc.isNullOrBlank()){
if (bean.mditationIndexInfo?.desc.isNullOrBlank()) {
"无常的日子里,呼吸间拾起力量"
}else{
} else {
bean.mditationIndexInfo?.desc
}
tv_meditation_slogan.text = slogan
val videoUrl = bean.mditationIndexInfo?.videoLink
val videoThumbnailUrl = bean.mditationIndexInfo?.mditationIndexUrl
if (videoUrl.isNullOrBlank()){
Glide.with(this)
.load(videoThumbnailUrl)
.transition(withCrossFade())
.into(iv_video_background)
}else{
GlideApp.with(this)
.load(videoThumbnailUrl)
.transition(withCrossFade())
.into(iv_video_background)
video_view?.setVideoPath(videoUrl)
video_view?.setOnErrorListener { mp, what, extra ->
Glide.with(this)
.load(bean.mditationIndexInfo?.mditationIndexUrl)
.transition(withCrossFade())
.into(iv_video_background)
true
}
video_view?.setOnPreparedListener {
it?.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING)
video_view?.setOnInfoListener { mp, what, extra ->
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START){
iv_video_background.visibility = View.GONE
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
video_view.setBackgroundColor(Color.TRANSPARENT)
}
true
}
it?.start()
it?.setVolume(0.0F,0.0F)
it?.setVolume(0.0F, 0.0F)
}
video_view?.setOnCompletionListener { video_view?.start() }
}
bean.mditationListResponse?.forEach {
meditationTitles.add(it.comment)
}
view_pager.adapter = MeditationViewPagerAdapter(mContext,bean)
view_pager.adapter = MeditationViewPagerAdapter(mContext, bean)
tab_layout.addOnTabSelectedListener(object :TabLayout.OnTabSelectedListener{
tab_layout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
var text:String? = tab?.text.toString().trim()
var text: String? = tab?.text.toString().trim()
val spStr = SpannableString(text)
val styleSpan = StyleSpan(Typeface.BOLD)
spStr.setSpan(styleSpan,0,text?.length?:0,Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
spStr.setSpan(styleSpan, 0, text?.length ?: 0, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
tab?.text = spStr
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
var text:String? = tab?.text.toString().trim()
var text: String? = tab?.text.toString().trim()
val spStr = SpannableString(text)
val styleSpan = StyleSpan(Typeface.NORMAL)
spStr.setSpan(styleSpan,0,text?.length?:0,Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
spStr.setSpan(styleSpan, 0, text?.length ?: 0, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
tab?.text = spStr
}
......@@ -177,8 +148,7 @@ class HomeMuseView(private val mContext: Context, private var homeEvent: IHomeEv
})
TabLayoutMediator(tab_layout,view_pager){
tab, position ->
TabLayoutMediator(tab_layout, view_pager) { tab, position ->
tab.text = meditationTitles[position]
}.attach()
......
......@@ -21,7 +21,8 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="#999999">
<com.yidianling.home.widget.AdaptiveVideoView
android:id="@+id/video_view"
......@@ -30,11 +31,11 @@
android:focusable="false"
android:focusableInTouchMode="false" />
<ImageView
android:id="@+id/iv_video_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"/>
<!-- <ImageView-->
<!-- android:id="@+id/iv_video_background"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:scaleType="fitCenter"/>-->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
......
......@@ -4,7 +4,6 @@ import android.content.Intent
import android.os.Bundle
import com.blankj.utilcode.util.SPUtils
import com.ydl.ydlcommon.base.BaseActivity
import com.ydl.ydlcommon.bean.StatusBarOptions
import com.ydl.ydlcommon.utils.StatusBarUtils
import com.ydl.ydlcommon.utils.remind.ToastHelper
import com.yidianling.muse.R
......@@ -85,12 +84,8 @@ class MeditationTimeOffActivity : BaseActivity() {
}
override fun getStatusViewOptions(): StatusBarOptions {
return StatusBarOptions(true, false)
}
override fun initDataAndEvent() {
StatusBarUtils.setWindowStatusBarColor(this, R.color.platform_main_theme)
}
override fun layoutResId(): Int {
......
......@@ -12,10 +12,10 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.ydl.webview.H5Params
import com.ydl.webview.NewH5Activity
import com.ydl.ydlcommon.base.BaseActivity
import com.ydl.ydlcommon.bean.StatusBarOptions
import com.ydl.ydlcommon.data.http.ThrowableConsumer
import com.ydl.ydlcommon.event.MeditationEvent
import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.utils.StatusBarUtils
import com.ydl.ydlcommon.utils.StatusBarUtils.Companion.setTransparentForImageView
import com.ydl.ydlcommon.utils.StatusBarUtils.Companion.statusBarLightMode
import com.ydl.ydlcommon.utils.Utils
......@@ -27,6 +27,7 @@ import com.yidianling.muse.bean.MeditationPlayModuleBean
import com.yidianling.muse.event.MeditationFloatEvent
import com.yidianling.muse.helper.MediaPlayerManager
import com.yidianling.muse.utils.MediaPlayerTimeUtil
import com.yidianling.muse.utils.MeditationFloatPermissionUtil
import com.yidianling.muse.widget.QuitMeditationDialog
import com.yidianling.muse.widget.ShareMeditationDialog
import com.yidianling.user.api.service.IUserService
......@@ -62,6 +63,7 @@ class PlayMeditationActivity : BaseActivity() {
private var meditations = mutableListOf<MeditationPlayModuleBean.MeditationDetail>()
private var currentMeditation: MeditationPlayModuleBean.MeditationDetail? = null
private var currentMeditationIndex = 0
private var shareTitle = ""
private var shareUrl = ""
......@@ -85,6 +87,9 @@ class PlayMeditationActivity : BaseActivity() {
private var mObservable: Observable<Long>? = null
private var mObserver: Observer<Long>? = null
private var status = 0
private var buried:String? = null
override fun onCreate(savedInstanceState: Bundle?) {
setTransparentForImageView(this, null)
statusBarLightMode(this)
......@@ -105,7 +110,7 @@ class PlayMeditationActivity : BaseActivity() {
}
override fun initDataAndEvent() {
StatusBarUtils.setWindowStatusBarColor(this, R.color.platform_main_theme)
}
private fun getData() {
......@@ -113,7 +118,6 @@ class PlayMeditationActivity : BaseActivity() {
if (meditationType == null || (mediaId == null && meditationType != 0)) {
return
}
// 声音详情
if (meditationType == 0) {
MuseHttp.getInstance().getPureMusicPlayDetail(
......@@ -142,7 +146,9 @@ class PlayMeditationActivity : BaseActivity() {
businessType = meditationPlayBean.businessType
val status = meditationPlayBean.status
status = meditationPlayBean.status
buried = meditationPlayBean.buried
collected = status == 1
......@@ -212,7 +218,9 @@ class PlayMeditationActivity : BaseActivity() {
businessType = meditationPlayBean.businessType
val status = meditationPlayBean.status
status = meditationPlayBean.status
buried = meditationPlayBean.buried
collected = status == 1
......@@ -329,10 +337,6 @@ class PlayMeditationActivity : BaseActivity() {
return R.layout.activity_play_meditation
}
override fun getStatusViewOptions(): StatusBarOptions {
return StatusBarOptions(true, false)
}
private fun initView() {
shareImageUrl = mediaCoverUrl
......@@ -378,10 +382,6 @@ class PlayMeditationActivity : BaseActivity() {
}
iv_back.setOnClickListener {
// MeditationViewModel.isVisible.postValue(true)
// MeditationViewModel.meditation.postValue(currentMeditation)
// MeditationViewModel.meditations.postValue(meditations as ArrayList<MeditationPlayModuleBean.MeditationDetail>)
// LogUtil.d("Lancet=======","post $currentMeditation")
val event = MeditationFloatEvent(true,meditationDetail = currentMeditation)
EventBus.getDefault().post(event)
......@@ -583,10 +583,46 @@ class PlayMeditationActivity : BaseActivity() {
})
initPlayCompletionListener()
}
private fun initPlayCompletionListener(isLoop:Boolean = false,isSingle:Boolean = false){
mMediaPlayer?.setOnCompletionListener {
postPlayRecord(isQuit = 0,
playTime = (seekbar_play_progress.progress / 1000.00).roundToInt(),
isComplete = 1)
if (isLoop){
if (isSingle || meditations.size == 1){
MediaPlayerManager.getInstance(this)?.setAudioPath(currentMeditation?.mediaUrl?:"")
}else{
currentMeditationIndex = meditations.indexOf(currentMeditation)
if(currentMeditationIndex == meditations.size - 1){
currentMeditationIndex = 0
}else{
currentMeditationIndex++
}
currentMeditation = meditations[currentMeditationIndex]
val event = MeditationEvent(
currentMeditation?.mediaId?.toInt()?:0,
meditationId?:0L,
meditationType?:0,
businessType,
status = status,
buried = buried?:"",
mediaUrl = currentMeditation?.mediaUrl?:"",
mediaCoverUrl = currentMeditation?.coverImageUrl?:"",
title = currentMeditation?.title?:"",
desc = currentMeditation?.desc?:""
)
EventBus.getDefault().post(event)
}
}
isPlaying = if (it.isPlaying) {
exo_play.setImageResource(R.drawable.icon_pause_play)
true
......@@ -598,7 +634,6 @@ class PlayMeditationActivity : BaseActivity() {
mMediaPlayer?.pause()
}
}
}
private fun postPlayRecord(isQuit: Int, playTime: Int, isComplete: Int) {
......@@ -704,22 +739,24 @@ class PlayMeditationActivity : BaseActivity() {
val minute = data?.extras?.getInt("TIME_OFF_MINUTE", 0)
if (minute != null && minute > 0) {
if (meditationType == 0) {
initPlayCompletionListener(isLoop = true,isSingle = true)
tv_time_off_pure_music.visibility = View.VISIBLE
tv_time_off.visibility = View.GONE
mDisposable?.dispose()
initRxTimeOff((minute * 60 * 1000).toLong(), 0)
} else {
initPlayCompletionListener(isLoop = true,isSingle = false)
tv_time_off_pure_music.visibility = View.GONE
tv_time_off.visibility = View.VISIBLE
mDisposable?.dispose()
initRxTimeOff((minute * 60 * 1000).toLong(), 1)
}
} else {
initPlayCompletionListener()
mDisposable?.dispose()
tv_time_off.visibility = View.GONE
tv_time_off_pure_music.visibility = View.GONE
mMediaPlayer?.isLooping = false
}
}
}
......@@ -798,19 +835,21 @@ class PlayMeditationActivity : BaseActivity() {
if (event.mediaUrl == MediaPlayerManager.getInstance(this)?.getAudioPath()) {
return
}
initMediaPlayer(event.mediaUrl, 0)
}
}
override fun onBackPressed() {
val event = MeditationFloatEvent(true,meditationDetail = currentMeditation)
EventBus.getDefault().post(event)
super.onBackPressed()
}
override fun onDestroy() {
super.onDestroy()
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this)
}
mDisposable?.dispose()
mTimer.cancel()
}
......
......@@ -27,8 +27,6 @@ class FloatViewTouchListener(val wl: WindowManager.LayoutParams, val windowManag
x += movedX
y += movedY
}
LogUtil.d("Lancet=======","nowY=====$nowY")
LogUtil.d("Lancet=======","movedY=====$movedY")
//更新悬浮窗位置
windowManager.updateViewLayout(view, wl)
}
......
......@@ -4,13 +4,18 @@ import android.content.Context
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.MediaPlayer
import com.yidianling.muse.helper.MediaPlayerManager.MediaPlayCallBack.Companion.TYPE_LIST
import kotlin.properties.Delegates
class MediaPlayerManager private constructor() {
private var listener:OnMediaPlayerManagerListener?=null
fun setAudioPath(path: String){
private var mCurrentListIndex = 0
private var mMediaPlayCallBack:MediaPlayCallBack?=null
private var mAudioPaths = mutableListOf<String>()
fun setAudioPath(path: String,isLoop:Boolean = false){
val attrs = AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
......@@ -26,6 +31,29 @@ class MediaPlayerManager private constructor() {
mMediaPlayer?.setOnPreparedListener {
listener?.onPrepared(it)
}
// mMediaPlayer?.setOnCompletionListener {
// if (it !=null){
// it.stop()
// it.release()
// }
//
// mMediaPlayer = null
// if (mAudioPaths!=null){
// mCurrentListIndex++
// if(mCurrentListIndex<mAudioPaths.size){
// mMediaPlayCallBack?.mediaPlayCallBack(TYPE_LIST,
// MediaPlayCallBack.STATE_CUT, mCurrentListIndex)
// setAudioPath(mAudioPaths[mCurrentListIndex])
// }else{
// mMediaPlayCallBack?.mediaPlayCallBack(TYPE_LIST,
// MediaPlayCallBack.STATE_STOP,mAudioPaths.size
// )
// }
// }
//
// }
}
fun getMediaPlayer():MediaPlayer? = mMediaPlayer
......@@ -59,6 +87,22 @@ class MediaPlayerManager private constructor() {
this.listener = listener
}
fun startPlayList(audioPaths:ArrayList<String>,
playCallBack: MediaPlayCallBack,startIndex:Int){
if(audioPaths.isNullOrEmpty() || startIndex>=mAudioPaths.size){
return
}
mMediaPlayCallBack = playCallBack
mAudioPaths = audioPaths
mCurrentListIndex = startIndex
mMediaPlayCallBack?.mediaPlayCallBack(TYPE_LIST,
MediaPlayCallBack.STATE_START,mCurrentListIndex)
setAudioPath(mAudioPaths[mCurrentListIndex])
}
companion object {
private var mContext: Context by Delegates.notNull()
......@@ -90,4 +134,23 @@ class MediaPlayerManager private constructor() {
fun onPrepared(mediaPlayer: MediaPlayer)
}
interface MediaPlayCallBack {
companion object{
const val STATE_START = 0
const val STATE_PLAY = 1
const val STATE_PAUSE = 2
const val STATE_STOP = 3
const val STATE_CUT = 4
const val TYPE_SINGLE = 0
const val TYPE_LIST = 1
}
fun mediaPlayCallBack(type:Int,state:Int,position:Int){}
}
}
\ No newline at end of file
package com.yidianling.muse.service
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.graphics.PixelFormat
......@@ -13,6 +17,7 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.WindowManager
import android.widget.ImageView
import android.widget.TextView
import androidx.core.app.NotificationCompat
import androidx.lifecycle.LifecycleService
import com.bumptech.glide.Glide
import com.ydl.ydlcommon.data.http.ThrowableConsumer
......@@ -21,7 +26,6 @@ import com.yidianling.muse.R
import com.yidianling.muse.activity.PlayMeditationActivity
import com.yidianling.muse.bean.MeditationPlayModuleBean
import com.yidianling.muse.event.MeditationFloatEvent
import com.yidianling.muse.helper.FloatViewTouchListener
import com.yidianling.muse.helper.MediaPlayerManager
import de.greenrobot.event.EventBus
import io.feeeei.circleseekbar.CircleSeekBar
......@@ -51,6 +55,18 @@ class MeditationWindowService : LifecycleService() {
override fun onCreate() {
super.onCreate()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel("壹点灵","play",NotificationManager.IMPORTANCE_LOW)
manager.createNotificationChannel(channel)
val notification = NotificationCompat.Builder(this,"壹点灵").build()
startForeground(1,notification)
}
}
EventBus.getDefault().register(this)
}
......@@ -66,30 +82,23 @@ class MeditationWindowService : LifecycleService() {
}
flags =
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
format = PixelFormat.RGBA_8888
width = outMetrics.widthPixels - dp2px(32F)
height = WRAP_CONTENT
gravity = Gravity.CENTER_HORIZONTAL or Gravity.TOP
gravity = Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM
x = outMetrics.widthPixels /2 - width / 2
y = outMetrics.heightPixels - height * 2
}
floatRootView =
LayoutInflater.from(this).inflate(R.layout.layout_meditation_play_float_view, null)
ivClose = floatRootView?.findViewById(R.id.iv_close)
ivCover = floatRootView?.findViewById(R.id.iv_cover)
tvTitle = floatRootView?.findViewById(R.id.tv_title)
ivProgress = floatRootView?.findViewById(R.id.progress_bar)
ivPlayOrPause = floatRootView?.findViewById(R.id.iv_play_status)
floatRootView?.setOnTouchListener(FloatViewTouchListener(layoutParams, mWindowManager))
// floatRootView?.setOnTouchListener(FloatViewTouchListener(layoutParams, mWindowManager))
mWindowManager.addView(floatRootView, layoutParams)
windowIsShow = true
}
......@@ -106,9 +115,7 @@ class MeditationWindowService : LifecycleService() {
}
private fun updateFloatView(meditation: MeditationPlayModuleBean.MeditationDetail) {
mMediaPlayer = MediaPlayerManager.getInstance(this)?.getMediaPlayer()
floatRootView?.setOnClickListener {
val intent = Intent(this, PlayMeditationActivity::class.java)
intent.putExtra("MEDIA_ID", meditation.mediaId)
......@@ -120,7 +127,6 @@ class MeditationWindowService : LifecycleService() {
}
if (mMediaPlayer?.isPlaying == true) {
ivPlayOrPause?.setImageResource(R.drawable.icon_meditation_float_play)
} else {
ivPlayOrPause?.setImageResource(R.drawable.icon_meditation_float_pause)
......@@ -180,6 +186,11 @@ class MeditationWindowService : LifecycleService() {
meditation.meditationId.toInt(),
meditation.mediaId ?: 0L
)
if (mMediaPlayer?.isPlaying == true) {
ivPlayOrPause?.setImageResource(R.drawable.icon_meditation_float_play)
} else {
ivPlayOrPause?.setImageResource(R.drawable.icon_meditation_float_pause)
}
}
ivClose?.setOnClickListener {
......@@ -199,17 +210,35 @@ class MeditationWindowService : LifecycleService() {
if (floatRootView != null && floatRootView?.windowToken != null) {
if (mWindowManager != null) {
windowIsShow = false
mTimer.cancel()
mWindowManager.removeViewImmediate(floatRootView)
}
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
startForegroundService(intent)
}else{
startService(intent)
}
}
return super.onStartCommand(intent, flags, startId)
}
override fun startForegroundService(service: Intent?): ComponentName? {
return super.startForegroundService(service)
}
override fun onDestroy() {
super.onDestroy()
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
stopForeground(true)
}
}
private fun dp2px(dp: Float): Int {
......
package com.yidianling.muse.utils
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
object MeditationFloatPermissionUtil {
const val REQUEST_FLOAT_CODE=1001
private fun commonROMPermissionCheck(context: Context?):Boolean {
var result = true
if (Build.VERSION.SDK_INT >= 23){
try {
val clazz:Class<*> = Settings::class.java
val canDrawOverlays = clazz.getDeclaredMethod("canDrawOverlays",Context::class.java)
result = canDrawOverlays.invoke(null, context) as Boolean
}catch (e:Exception){
}
}
return result
}
fun checkSuspendedWindowPermission(context: Activity,block:() -> Unit){
if(commonROMPermissionCheck(context)){
block
}else{
context.startActivityForResult(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION).apply {
data = Uri.parse("package:${context.packageName}")
}, REQUEST_FLOAT_CODE)
}
}
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="@drawable/bg_play_meditation_float_view"
android:background="@drawable/play_float_background"
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment