Commit 69d550ff by konghaorui

Merge branch 'dev' of ssh://gitlab.yidianling.com:2224/app_android_lib/YDL-Component into dev

# Conflicts:
#	config.gradle
#	m-course/build.gradle
parents 8a206296 61dca5e5
...@@ -9,6 +9,7 @@ import com.ydl.devicesidlib.DeviceIDHelper; ...@@ -9,6 +9,7 @@ import com.ydl.devicesidlib.DeviceIDHelper;
import com.ydl.media.audio.PlayService; import com.ydl.media.audio.PlayService;
import com.ydl.ydlcommon.base.delegate.IAppLifecycles; import com.ydl.ydlcommon.base.delegate.IAppLifecycles;
import com.ydl.ydlcommon.utils.YdlBuryPointUtil; import com.ydl.ydlcommon.utils.YdlBuryPointUtil;
import com.yidianling.course.lifeCallback.CoursePlayLifecycle;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
...@@ -37,6 +38,8 @@ public class DemoAppLifecycles implements IAppLifecycles { ...@@ -37,6 +38,8 @@ public class DemoAppLifecycles implements IAppLifecycles {
Intent intent = new Intent(application, PlayService.class); Intent intent = new Intent(application, PlayService.class);
application.startService(intent); application.startService(intent);
application.registerActivityLifecycleCallbacks(new CoursePlayLifecycle());
} }
@Override @Override
......
...@@ -27,7 +27,7 @@ public final class DemoGlobalConfig implements IConfigModule { ...@@ -27,7 +27,7 @@ public final class DemoGlobalConfig implements IConfigModule {
public void applyOptions(@NotNull Context context, @NotNull GlobalConfig.Builder builder) { public void applyOptions(@NotNull Context context, @NotNull GlobalConfig.Builder builder) {
builder.setFrom( "ydl".equals(BuildConfig.FLAVOR) ?YDLConstants.FROM_YDL :YDLConstants.FROM_XLZX) builder.setFrom( "ydl".equals(BuildConfig.FLAVOR) ?YDLConstants.FROM_YDL :YDLConstants.FROM_XLZX)
.addUrl("github", APP_DOMAIN) .addUrl("github", APP_DOMAIN)
.setEnv(YDLConstants.ENV_TEST) .setEnv(YDLConstants.ENV_PROD)
.setDebug(BuildConfig.DEBUG); .setDebug(BuildConfig.DEBUG);
} }
} }
...@@ -20,7 +20,9 @@ import com.ydl.media.audio.model.Music; ...@@ -20,7 +20,9 @@ import com.ydl.media.audio.model.Music;
import com.ydl.media.audio.utils.CoverImageUtils; import com.ydl.media.audio.utils.CoverImageUtils;
import com.ydl.media.view.PlayTypeEnum; import com.ydl.media.view.PlayTypeEnum;
import com.ydl.media.view.PlayerFloatHelper; import com.ydl.media.view.PlayerFloatHelper;
import com.ydl.ydlcommon.utils.LogUtil;
import com.yidianling.common.tools.ToastUtil; import com.yidianling.common.tools.ToastUtil;
import com.yidianling.user.LoginUtils;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
...@@ -297,6 +299,6 @@ public class PlayFragment extends Fragment implements View.OnClickListener, ...@@ -297,6 +299,6 @@ public class PlayFragment extends Fragment implements View.OnClickListener,
@Override @Override
public void onComplete() { public void onComplete() {
LogUtil.e("onComplete");
} }
} }
...@@ -31,12 +31,24 @@ class ConsultAssistantDialogUtils private constructor() { ...@@ -31,12 +31,24 @@ class ConsultAssistantDialogUtils private constructor() {
* origin 展示请求来源 首页 home_index 咨询列表 doctor_list * origin 展示请求来源 首页 home_index 咨询列表 doctor_list
*/ */
fun fitRequest(activity: Activity, origin: String) { fun fitRequest(activity: Activity, origin: String) {
if (ConsultantIn.isLogin() && when (origin) {
ConsultantIn.getUserImpl().getUserInfo()?.user_type == 1 "home_index" -> {
/** WalleChannelReader.getChannel(BaseApp.Companion.getApp()) == "android_huawei" */ if (ConsultantIn.isLogin() &&
) { ConsultantIn.getUserImpl().getUserInfo()?.user_type == 1
shouldShowDialog(activity, origin) /** WalleChannelReader.getChannel(BaseApp.Companion.getApp()) == "android_huawei" */
) {
shouldShowDialog(activity, origin)
}
}
"doctor_list" -> {
if (ConsultantIn.getUserImpl().getUserInfo()?.user_type == 1
/** WalleChannelReader.getChannel(BaseApp.Companion.getApp()) == "android_huawei" */
) {
shouldShowDialog(activity, origin)
}
}
} }
} }
/** /**
...@@ -101,7 +113,7 @@ class ConsultAssistantDialogUtils private constructor() { ...@@ -101,7 +113,7 @@ class ConsultAssistantDialogUtils private constructor() {
expertSearchPageHasShown = true expertSearchPageHasShown = true
} }
} }
}, 10000) }, 5000)
} else { } else {
showDialog(activity) showDialog(activity)
} }
......
...@@ -62,6 +62,8 @@ dependencies { ...@@ -62,6 +62,8 @@ dependencies {
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
kapt 'com.alibaba:arouter-compiler:1.2.2' kapt 'com.alibaba:arouter-compiler:1.2.2'
api 'com.github.princekin-f:EasyFloat:1.1.2'
api rootProject.ext.dependencies["ydl-user-router"] api rootProject.ext.dependencies["ydl-user-router"]
api rootProject.ext.dependencies["butterknife"] api rootProject.ext.dependencies["butterknife"]
if (rootProject.ext.dev_mode){ if (rootProject.ext.dev_mode){
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yidianling.course"> xmlns:tools="http://schemas.android.com/tools"
package="com.yidianling.course">
<uses-sdk tools:overrideLibrary="com.lzf.easyfloat"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application> <application>
<!--课程首页--> <!--课程首页-->
<activity <activity
...@@ -42,6 +48,7 @@ ...@@ -42,6 +48,7 @@
android:name=".course_special_list.activity.CourseSpecialListActivity" android:name=".course_special_list.activity.CourseSpecialListActivity"
android:screenOrientation="portrait" /> android:screenOrientation="portrait" />
<service android:name="com.lzf.easyfloat.service.FloatService" />
</application> </application>
</manifest> </manifest>
...@@ -68,26 +68,26 @@ class CoursePlayItemViewAudio : RelativeLayout, PlayViewInterface { ...@@ -68,26 +68,26 @@ class CoursePlayItemViewAudio : RelativeLayout, PlayViewInterface {
playView?.listener = object : HPlayStatusListener { playView?.listener = object : HPlayStatusListener {
override fun isCanPlay(data: Music?): Boolean { override fun isCanPlay(data: Music?): Boolean {
var canPlay = false var canPlay = false
//非试听 //非试听
if (courseExtra!!.isBuy) { if (courseExtra!!.isBuy) {
//已购买 //已购买
canPlay = true canPlay = true
} else { } else {
//未购买,判断是否是试听课程 //未购买,判断是否是试听课程
//即未购买,也不是试听,弹窗提示 //即未购买,也不是试听,弹窗提示
if (activity == null) return false if (activity == null) return false
CommonDialog(activity) CommonDialog(activity)
.setMessage("\n购买课程,获取完整课程内容\n") .setMessage("\n购买课程,获取完整课程内容\n")
.setLeftOnclick("放弃") { .setLeftOnclick("放弃") {
} }
.setRightClick("购买") { .setRightClick("购买") {
//跳转支付页 //跳转支付页
activity?.addCourseOrder() activity?.addCourseOrder()
} }
.setCancelAble(false) .setCancelAble(false)
.show() .show()
} }
return canPlay return canPlay
} }
...@@ -102,7 +102,12 @@ class CoursePlayItemViewAudio : RelativeLayout, PlayViewInterface { ...@@ -102,7 +102,12 @@ class CoursePlayItemViewAudio : RelativeLayout, PlayViewInterface {
/** /**
* 设置显示数据 * 设置显示数据
*/ */
override fun setData(index: Int, list: ArrayList<CourseMediaBean>, courseExtra: CourseExtraBean, from: Int) { override fun setData(
index: Int,
list: ArrayList<CourseMediaBean>,
courseExtra: CourseExtraBean,
from: Int
) {
if (list.isEmpty()) return if (list.isEmpty()) return
playList.clear() playList.clear()
...@@ -110,8 +115,6 @@ class CoursePlayItemViewAudio : RelativeLayout, PlayViewInterface { ...@@ -110,8 +115,6 @@ class CoursePlayItemViewAudio : RelativeLayout, PlayViewInterface {
this.courseExtra = courseExtra this.courseExtra = courseExtra
currentIndex = index currentIndex = index
// YDLMusicHelper.course_id = courseExtra.id.toInt()
if (courseExtra.isBuy) { if (courseExtra.isBuy) {
playView?.setAutoNext(true) playView?.setAutoNext(true)
} else { } else {
......
...@@ -208,9 +208,12 @@ class CourseSearchActivity : BaseActivity(), CourseSearchAdapter.OnItemClick, IC ...@@ -208,9 +208,12 @@ class CourseSearchActivity : BaseActivity(), CourseSearchAdapter.OnItemClick, IC
hideUnusualPage() hideUnusualPage()
if (type) { if (type) {
courseList.clear() courseList.clear()
courseList.addAll(it.data.list)
courseSearchAdapterWrapper!!.notifyDataSetChanged()
} else {
courseList.addAll(it.data.list)
courseSearchAdapterWrapper!!.insertData()
} }
courseList.addAll(it.data.list)
courseSearchAdapterWrapper!!.insertData()
} else { } else {
if (!type) { if (!type) {
courseSearchAdapterWrapper!!.noMoreData() courseSearchAdapterWrapper!!.noMoreData()
......
package com.yidianling.course.courseSearch.http package com.yidianling.course.courseSearch.http
import com.ydl.ydlcommon.base.config.YDL_DOMAIN
import com.ydl.ydlcommon.base.config.YDL_DOMAIN_JAVA
import com.ydl.ydlcommon.data.http.BaseAPIResponse import com.ydl.ydlcommon.data.http.BaseAPIResponse
import com.yidianling.course.courseSearch.CourseSearchBean import com.yidianling.course.courseSearch.CourseSearchBean
import io.reactivex.Observable import io.reactivex.Observable
...@@ -16,5 +18,6 @@ interface CourseSearchListApi{ ...@@ -16,5 +18,6 @@ interface CourseSearchListApi{
//专家课程搜索列表 //专家课程搜索列表
@GET("auth/course/getList") @GET("auth/course/getList")
@Headers(YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun courseSearchList(@Query("page")page: Int, @Query("keyWord")keyWord: String): Observable<BaseAPIResponse<CourseSearchBean>> fun courseSearchList(@Query("page")page: Int, @Query("keyWord")keyWord: String): Observable<BaseAPIResponse<CourseSearchBean>>
} }
\ No newline at end of file
import android.app.AlertDialog
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Handler import android.os.Handler
import android.text.TextUtils import android.text.TextUtils
import com.lzf.easyfloat.permission.PermissionUtils
import com.ydl.media.audio.AudioPlayer import com.ydl.media.audio.AudioPlayer
import com.ydl.media.audio.model.Music import com.ydl.media.audio.model.Music
import com.ydl.media.view.PlayTypeEnum import com.ydl.media.view.PlayTypeEnum
...@@ -16,13 +18,14 @@ import com.ydl.ydlcommon.data.PlatformDataManager ...@@ -16,13 +18,14 @@ import com.ydl.ydlcommon.data.PlatformDataManager
import com.ydl.ydlcommon.modular.ModularServiceManager import com.ydl.ydlcommon.modular.ModularServiceManager
import com.yidianling.common.tools.LogUtil import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxDeviceTool import com.yidianling.common.tools.RxDeviceTool
import com.yidianling.course.BuildConfig import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.CourseConstants import com.yidianling.course.CourseConstants
import com.yidianling.course.bean.ScrollStatusChangeEvent import com.yidianling.course.bean.ScrollStatusChangeEvent
import com.yidianling.course.courseNew.mine.MyCourseActivity import com.yidianling.course.courseNew.mine.MyCourseActivity
import com.yidianling.course.course_special_list.activity.CourseSpecialListActivity import com.yidianling.course.course_special_list.activity.CourseSpecialListActivity
import com.yidianling.course.flutterPlugin.CourseSendPlugin import com.yidianling.course.flutterPlugin.CourseSendPlugin
import com.yidianling.course.router.CourseIn import com.yidianling.course.router.CourseIn
import com.yidianling.course.widget.VideoFloatHelper
import de.greenrobot.event.EventBus import de.greenrobot.event.EventBus
import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
...@@ -66,7 +69,7 @@ class CoursePlugin : MethodChannel.MethodCallHandler { ...@@ -66,7 +69,7 @@ class CoursePlugin : MethodChannel.MethodCallHandler {
val loginBean = ModularServiceManager.getPlatformUserService()?.getUser() val loginBean = ModularServiceManager.getPlatformUserService()?.getUser()
val mMap = mutableMapOf<String, Any>() val mMap = mutableMapOf<String, Any>()
var uid = loginBean?.userId ?: "" var uid = loginBean?.userId ?: ""
mMap["isDevelopment"] = BuildConfig.DEBUG mMap["isDevelopment"] = false
mMap["uid"] = if (TextUtils.isEmpty(uid)) "0" else uid mMap["uid"] = if (TextUtils.isEmpty(uid)) "0" else uid
mMap["accessToken"] = loginBean?.token ?: "" mMap["accessToken"] = loginBean?.token ?: ""
?: "" ?: ""
...@@ -92,11 +95,21 @@ class CoursePlugin : MethodChannel.MethodCallHandler { ...@@ -92,11 +95,21 @@ class CoursePlugin : MethodChannel.MethodCallHandler {
return return
} }
when { when {
jumpUrl!!.contains("user/login") -> mFragment!!.startActivity( jumpUrl!!.contains("user/login") -> {
CourseIn.loginWayIntent( //TODO flutter 登录状态判断需要更改
mFragment!!.activity!! val loginBean =
) ModularServiceManager.getPlatformUserService()?.getUser()
) if (loginBean == null || TextUtils.isEmpty(loginBean.userId) || TextUtils.equals(
loginBean.userId,
"0"
)
) {
mFragment!!.startActivity(CourseIn.loginWayIntent(mFragment!!.activity!!))
} else {
MyCourseActivity.start(mFragment!!.activity)
}
}
jumpUrl.contains("course/myCourse") -> MyCourseActivity.start(mFragment!!.activity) jumpUrl.contains("course/myCourse") -> MyCourseActivity.start(mFragment!!.activity)
jumpUrl.contains("course/specialList") -> //跳转专题列表页 jumpUrl.contains("course/specialList") -> //跳转专题列表页
mFragment!!.activity!!.startActivity( mFragment!!.activity!!.startActivity(
...@@ -177,20 +190,29 @@ class CoursePlugin : MethodChannel.MethodCallHandler { ...@@ -177,20 +190,29 @@ class CoursePlugin : MethodChannel.MethodCallHandler {
if (demoType == 1) { if (demoType == 1) {
music.path = url music.path = url
val hashMap = HashMap<String, String>()
hashMap["course_id"] = fileInfo["courseId"].toString()
AudioPlayer.get().singlePlay(music) AudioPlayer.get().singlePlay(music)
PlayerFloatHelper.show( PlayerFloatHelper.show(
mFragment!!.activity, mFragment!!.activity,
playTypeEnum = PlayTypeEnum.PLAY_TYPE_COURSE playTypeEnum = PlayTypeEnum.PLAY_TYPE_COURSE,
playData = hashMap
) )
VideoFloatHelper.dismissFloat(mFragment!!.activity)
} }
if (demoType == 2) { if (demoType == 2) {
//todo 视屏播放 VideoFloatHelper.setVideoInfo(
// YDLMusicHelper.playType = 1 fileInfo["courseId"].toString(),
// YDLMusicHelper.courseVideoUlr = url fileInfo["url"].toString(),
// false
// PlayerFloatHelper.show(mFragment!!.activity) )
checkPermission()
if (PlayerFloatHelper.isShow(mFragment!!.activity!!)) {
PlayerFloatHelper.hide()
PlayerFloatHelper.removeView(mFragment!!.activity!!)
AudioPlayer.get().stopPlayer()
}
} }
Handler().postDelayed({ CourseSendPlugin.sendMsg(true) }, 300) Handler().postDelayed({ CourseSendPlugin.sendMsg(true) }, 300)
...@@ -215,4 +237,28 @@ class CoursePlugin : MethodChannel.MethodCallHandler { ...@@ -215,4 +237,28 @@ class CoursePlugin : MethodChannel.MethodCallHandler {
} }
}) })
} }
/**
* 检测浮窗权限是否开启,若没有给与申请提示框(非必须,申请依旧是EasyFloat内部内保进行)
*/
private fun checkPermission() {
if (PermissionUtils.checkPermission(mFragment!!.activity)) {
VideoFloatHelper.showVideoFloat(mFragment!!.activity)
} else {
AlertDialog.Builder(mFragment!!.activity)
.setMessage("使用浮窗功能,需要您授权悬浮窗权限。")
.setPositiveButton("去开启") { _, _ ->
VideoFloatHelper.showVideoFloat(mFragment!!.activity)
}
.setNegativeButton("取消") { _, _ ->
ToastUtil.toastLong(
mFragment!!.activity,
"App正常工作需要内部存储使用权限,请开启"
)
}
.show()
}
}
} }
\ No newline at end of file
package com.yidianling.course.lifeCallback
import android.app.Activity
import android.app.Application
import android.os.Bundle
import com.ydl.media.audio.AudioPlayer
import com.ydl.media.view.PlayTypeEnum
import com.ydl.media.view.PlayerFloatHelper
/**
* @author jiucheng
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/11/19
*/
class CoursePlayLifecycle : Application.ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity?) {
}
override fun onActivityResumed(activity: Activity?) {
if (!PlayerFloatHelper.isCanClick) {
PlayerFloatHelper.hide()
PlayerFloatHelper.removeView(activity!!)
AudioPlayer.get().stopPlayer()
} else {
PlayerFloatHelper.showIfPlaying(activity!!)
PlayerFloatHelper.playingType = PlayTypeEnum.PLAY_TYPE_COURSE
}
}
override fun onActivityStarted(activity: Activity?) {
}
override fun onActivityDestroyed(activity: Activity?) {
}
override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
}
override fun onActivityStopped(activity: Activity?) {
}
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
}
}
\ No newline at end of file
package com.yidianling.course.uitls
import android.content.Context
import android.text.TextUtils
/**
* 工具类
* Created by hgw on 2018/3/31.
*/
object VideoProgressUtil {
/**
* 保存播放进度
*/
fun saveProgress(context: Context?, url: String?, progress: Int) {
if (TextUtils.isEmpty(url)) return
val shared = context?.getSharedPreferences("COURSE_VIDEO_PROGRESS", Context.MODE_PRIVATE)
val edit = shared?.edit()
edit?.putInt(url, progress)
edit?.apply()
}
/**
* 获取进度
*/
fun getProgress(context: Context?, url: String?): Int {
if (TextUtils.isEmpty(url)) return 0
val shared = context?.getSharedPreferences("COURSE_VIDEO_PROGRESS", Context.MODE_PRIVATE)
return shared?.getInt(url, 0) ?: 0
}
}
\ No newline at end of file
package com.yidianling.course.widget package com.yidianling.course.widget
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.graphics.Paint import android.graphics.Paint
import android.support.constraint.ConstraintLayout import android.support.constraint.ConstraintLayout
...@@ -8,6 +10,7 @@ import android.text.TextUtils ...@@ -8,6 +10,7 @@ import android.text.TextUtils
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.lzf.easyfloat.permission.PermissionUtils
import com.ydl.media.audio.AudioPlayer import com.ydl.media.audio.AudioPlayer
import com.ydl.media.audio.model.Music import com.ydl.media.audio.model.Music
import com.ydl.media.view.PlayTypeEnum import com.ydl.media.view.PlayTypeEnum
...@@ -19,6 +22,7 @@ import com.ydl.ydl_image.module.GlideApp ...@@ -19,6 +22,7 @@ import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils
import com.ydl.ydlcommon.utils.actionutil.BIConstants import com.ydl.ydlcommon.utils.actionutil.BIConstants
import com.yidianling.common.tools.RxImageTool import com.yidianling.common.tools.RxImageTool
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.CourseConstants import com.yidianling.course.CourseConstants
import com.yidianling.course.R import com.yidianling.course.R
import com.yidianling.course.bean.Course import com.yidianling.course.bean.Course
...@@ -228,14 +232,30 @@ class CourseItemNewView : ConstraintLayout { ...@@ -228,14 +232,30 @@ class CourseItemNewView : ConstraintLayout {
PlayerFloatHelper.playingType=PlayTypeEnum.PLAY_TYPE_COURSE PlayerFloatHelper.playingType=PlayTypeEnum.PLAY_TYPE_COURSE
music.path=course.demoFile music.path=course.demoFile
val hashMap = HashMap<String, String>()
hashMap["course_id"] =course.id.toString()
AudioPlayer.get().singlePlay(music) AudioPlayer.get().singlePlay(music)
PlayerFloatHelper.show(
mContext,
playTypeEnum = PlayTypeEnum.PLAY_TYPE_COURSE,
playData = hashMap
)
VideoFloatHelper.dismissFloat(mContext as Activity)
} }
if (course.demoType == 2) { if (course.demoType == 2) {
//todo 视屏播放 VideoFloatHelper.setVideoInfo(
// YDLMusicHelper.playType = 1 course.id.toString(),
// YDLMusicHelper.courseVideoUlr = course.demoFile course.demoFile,
// false
// PlayerFloatHelper.show(mContext) )
checkPermission()
if (PlayerFloatHelper.isShow(mContext)) {
PlayerFloatHelper.hide()
PlayerFloatHelper.removeView(mContext)
AudioPlayer.get().stopPlayer()
}
} }
...@@ -269,4 +289,27 @@ class CourseItemNewView : ConstraintLayout { ...@@ -269,4 +289,27 @@ class CourseItemNewView : ConstraintLayout {
fun hideListenerButton() { fun hideListenerButton() {
tv_view_course.visibility = View.GONE tv_view_course.visibility = View.GONE
} }
/**
* 检测浮窗权限是否开启,若没有给与申请提示框(非必须,申请依旧是EasyFloat内部内保进行)
*/
private fun checkPermission() {
if (PermissionUtils.checkPermission(mContext)) {
VideoFloatHelper.showVideoFloat(mContext as Activity)
} else {
AlertDialog.Builder(mContext)
.setMessage("使用浮窗功能,需要您授权悬浮窗权限。")
.setPositiveButton("去开启") { _, _ ->
VideoFloatHelper.showVideoFloat(mContext as Activity)
}
.setNegativeButton("取消") { _, _ ->
ToastUtil.toastLong(
mContext,
"App正常工作需要内部存储使用权限,请开启"
)
}
.show()
}
}
} }
\ No newline at end of file
package com.yidianling.course.widget package com.yidianling.course.widget
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.os.Handler import android.os.Handler
import android.view.View import android.view.View
...@@ -36,8 +37,8 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -36,8 +37,8 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
fun init() { fun init() {
if (mContext == null) return if (mContext == null) return
View.inflate(context, R.layout.course_play_music_view, this) View.inflate(context, R.layout.course_play_music_view, this)
AudioPlayer.get().addOnPlayEventListener(this)
play_icon.setOnClickListener { play_icon.setOnClickListener {
AudioPlayer.get().playPause() AudioPlayer.get().playPause()
...@@ -48,8 +49,6 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -48,8 +49,6 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
} }
} }
AudioPlayer.get().addOnPlayEventListener(this)
pro_progress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { pro_progress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) { override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
if (p2) { if (p2) {
...@@ -114,9 +113,9 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -114,9 +113,9 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
} }
fun play(index: Int) { fun play(index: Int) {
updateButton() PlayerFloatHelper.playingType = PlayTypeEnum.PLAY_TYPE_COURSE
PlayerFloatHelper.playingType=PlayTypeEnum.PLAY_TYPE_COURSE
AudioPlayer.get().play(index) AudioPlayer.get().play(index)
updateButton()
} }
fun setImageBackground(url: String?) { fun setImageBackground(url: String?) {
...@@ -127,14 +126,23 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -127,14 +126,23 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
* 设置自动播放下一曲 * 设置自动播放下一曲
*/ */
fun setAutoNext(auto: Boolean) { fun setAutoNext(auto: Boolean) {
if(!auto){ if (!auto) {
AudioPlayer.get().playMode=PlayModeEnum.SINGLE AudioPlayer.get().playMode = PlayModeEnum.SINGLE
} else {
AudioPlayer.get().playMode = PlayModeEnum.LIST_LOOP
} }
} }
@SuppressLint("SetTextI18n")
override fun onChange(music: Music) { override fun onChange(music: Music) {
if (mContext != null) {
Glide.with(mContext).asGif().load(R.drawable.course_loading5).into(img_gif)
}
play_icon.setImageResource(R.drawable.course_ico_course_play)
pro_progress.progress = 0
text_start_time.text = "00:00"
} }
override fun onPlayerStart() { override fun onPlayerStart() {
...@@ -142,21 +150,18 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -142,21 +150,18 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
} }
override fun onPlayerPause() { override fun onPlayerPause() {
if (AudioPlayer.get().isPlaying){ if (AudioPlayer.get().isPlaying) {
setGifVisibity(true) setGifVisibity(true)
}else{ } else {
setGifVisibity(false) setGifVisibity(false)
} }
} }
override fun onPublish(percent: Int, currentPosition: Long) { override fun onPublish(percent: Int, currentPosition: Long) {
mHandler?.postDelayed({ if (!seekBarIsDown) {
//拖动seekbar时不进行以下操作 pro_progress.progress = currentPosition.toInt()
if (!seekBarIsDown) { text_start_time.text = getStringTime(currentPosition.toInt())
pro_progress.progress = progress }
text_start_time.text = getStringTime(progress)
}
}, 0)
} }
override fun onBufferingUpdate(percent: Int) { override fun onBufferingUpdate(percent: Int) {
...@@ -170,7 +175,7 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -170,7 +175,7 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
mHandler?.postDelayed({ mHandler?.postDelayed({
pro_progress.max = duration.toInt() pro_progress.max = duration.toInt()
text_end_time.text = getStringTime(pro_progress.max) text_end_time.text = getStringTime(pro_progress.max)
var index=AudioPlayer.get().getMusicList()?.indexOf(AudioPlayer.get().playMusic)?:0 var index = AudioPlayer.get().getMusicList()?.indexOf(AudioPlayer.get().playMusic) ?: 0
listener?.onPrepared( listener?.onPrepared(
AudioPlayer.get().playMusic, index AudioPlayer.get().playMusic, index
) )
...@@ -186,11 +191,12 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -186,11 +191,12 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
private fun showBufferLoading(show: Boolean) { private fun showBufferLoading(show: Boolean) {
mHandler?.postDelayed({ mHandler?.postDelayed({
if (show) { if (show) {
if (mContext != null) { if (!AudioPlayer.get().isPlaying) {
Glide.with(mContext).asGif().load(R.drawable.course_loading5).into(img_gif) if (mContext != null) {
Glide.with(mContext).asGif().load(R.drawable.course_loading5).into(img_gif)
}
play_icon.setImageResource(R.drawable.course_ico_course_play)
} }
play_icon.setImageResource(R.drawable.course_ico_course_play)
} else { } else {
if (mContext != null) { if (mContext != null) {
Glide.with(mContext).asGif().load(R.drawable.course_audio_play).into(img_gif) Glide.with(mContext).asGif().load(R.drawable.course_audio_play).into(img_gif)
...@@ -202,17 +208,14 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -202,17 +208,14 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
//显示或隐藏播放动画 //显示或隐藏播放动画
private fun setGifVisibity(show: Boolean) { private fun setGifVisibity(show: Boolean) {
if (context == null) return if (mContext == null) return
mHandler?.postDelayed({ mHandler?.postDelayed({
if (show) { if (show) {
if (mContext != null) { Glide.with(mContext).asGif().load(R.drawable.course_audio_play).into(img_gif)
Glide.with(mContext).asGif().load(R.drawable.course_audio_play).into(img_gif)
}
play_icon.setImageResource(R.drawable.course_ico_course_pause) play_icon.setImageResource(R.drawable.course_ico_course_pause)
} else { } else {
if (mContext != null) { Glide.with(mContext).asBitmap().load(R.drawable.course_ico_course_bg_pause)
Glide.with(mContext).asBitmap().load(R.drawable.course_ico_course_bg_pause).into(img_gif) .into(img_gif)
}
play_icon.setImageResource(R.drawable.course_ico_course_play) play_icon.setImageResource(R.drawable.course_ico_course_play)
} }
}, 0) }, 0)
...@@ -225,7 +228,7 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -225,7 +228,7 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
if (AudioPlayer.get().isPlaying) { if (AudioPlayer.get().isPlaying) {
setGifVisibity(true) setGifVisibity(true)
} }
}, 0) }, 300)
} }
......
package com.yidianling.course.widget
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.view.View
import android.widget.ImageView
import com.alibaba.android.arouter.launcher.ARouter
import com.dou361.ijkplayer.widget.PlayStateParams
import com.dou361.ijkplayer.widget.PlayerView
import com.lzf.easyfloat.EasyFloat
import com.lzf.easyfloat.enums.ShowPattern
import com.lzf.easyfloat.interfaces.OnInvokeView
import com.ydl.media.audio.utils.PlayProgressUtil
import com.yidianling.common.tools.RxDeviceTool
import com.yidianling.common.tools.RxImageTool
import com.yidianling.course.R
import com.yidianling.course.coursePlay.CoursePlayActivity
import com.yidianling.course.flutterPlugin.CourseSendPlugin
import com.yidianling.course.uitls.VideoProgressUtil
import java.util.*
/**
* @author jiucheng
* @描述:视频悬浮窗
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/11/19
*/
object VideoFloatHelper {
private const val courseTag = "course_video_play"
var courseVideoUrl = ""
var courseId = ""
var isCanClick = true
var isCurrentVideoPlaying = true
//视频播放器view
@SuppressLint("StaticFieldLeak")
private var videoView: PlayerView? = null
private var timer: Timer? = null
var defaultShowPattern = ShowPattern.CURRENT_ACTIVITY
fun setVideoInfo(
courseId: String,
courseVideoUrl: String,
isCanClick: Boolean
): VideoFloatHelper {
this.courseId = courseId
this.courseVideoUrl = courseVideoUrl
this.isCanClick = isCanClick
return this
}
fun showVideoFloat(activity: Activity) {
val x = RxDeviceTool.getScreenWidth(activity) - RxImageTool.dp2px(220f)
val y = RxDeviceTool.getScreenHeight(activity) * 3 / 4
EasyFloat.with(activity)
.setTag(courseTag)
.setShowPattern(defaultShowPattern)
.setLocation(x, y)
.setAppFloatAnimator(null)
.setFilter(CoursePlayActivity::class.java)
.setLayout(R.layout.course_float_video_view, OnInvokeView {
it.findViewById<ImageView>(R.id.iv_video_close).setOnClickListener {
dismissFloat(activity)
}
val videoFullScreen = it.findViewById<ImageView>(R.id.iv_video_full_screen)
if (isCanClick) {
videoFullScreen.visibility = View.VISIBLE
} else {
videoFullScreen.visibility = View.INVISIBLE
}
videoFullScreen.setOnClickListener {
if (isCanClick) {
startCoursePlayActivity(activity, 1, 1, courseVideoUrl, true)
}
}
val videoLayout = it.findViewById<ImageView>(R.id.app_video_box)
try {
initVideoPlayer(activity, videoLayout)
} catch (e: Exception) {
e.printStackTrace()
}
})
.show()
}
private fun initVideoPlayer(activity: Activity, view: View) {
val url = courseVideoUrl.replace("https", "http")
val hisTime = PlayProgressUtil.getProgress(activity, url)
videoView = PlayerView(activity, view)
.setScaleType(PlayStateParams.fitparent)
.hideAllUI()
.setNetWorkTypeTie(false)
.setAutoReConnect(true, 3)
.forbidTouch(true)
.setOnInfoListener { _, what, _ ->
if (what == PlayStateParams.STATE_COMPLETED) {
isCurrentVideoPlaying = false
PlayProgressUtil.saveProgress(activity, url, 0)
} else {
isCurrentVideoPlaying = true
}
true
}
.setPlaySource(url)
.startPlay()
.seekTo(hisTime)
view.setOnClickListener {
if (isCanClick) {
startCoursePlayActivity(activity, 1, 0, courseVideoUrl, true)
}
}
startTimer(url, activity)
}
private fun startTimer(url: String, activity: Activity) {
if (timer == null) {
timer = Timer()
}
timer?.schedule(object : TimerTask() {
override fun run() {
if (isCurrentVideoPlaying) {
var time = videoView?.currentPosition ?: 0
if (time < 3000) return
PlayProgressUtil.saveProgress(activity, url, time)
}
}
}, 1000, 1000)
}
private fun startCoursePlayActivity(
context: Context?,
from: Int,
fullScreen: Int,
coursePlayUrl: String,
isFromFloatView: Boolean
) {
ARouter.getInstance()
.build("/course/play")
.withInt("course_id", courseId.toInt())
.withInt("course_type", 1)
.withString("coursePlayUrl", coursePlayUrl)
.withInt("from", from)
.withBoolean("isFromFloatView", isFromFloatView)
.withInt("fullScreen", fullScreen)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.navigation()
}
fun dismissFloat(activity: Activity) {
CourseSendPlugin.sendMsg(false)
EasyFloat.dismissAppFloat(activity, courseTag)
if (videoView != null) {
videoView!!.stopPlay()
videoView = null
}
if (timer != null) {
timer!!.cancel()
}
timer = null
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_video_layout"
android:layout_width="200dp"
android:layout_height="124dp"
android:background="@drawable/play_float_background"
android:visibility="visible">
<include
layout="@layout/course_videoplay_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/iv_video_close"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:padding="8dp"
android:scaleType="centerCrop"
android:src="@drawable/ico_play_float_pause"
android:visibility="visible" />
<ImageView
android:id="@+id/iv_video_full_screen"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:padding="8dp"
android:scaleType="centerCrop"
android:src="@drawable/course_ico_play_float_full"
android:visibility="visible" />
</RelativeLayout>
\ No newline at end of file
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