Commit 2326a717 by 严久程

咨询加声网

parent 71ff661f
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ydl.audioim">
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<application>
<activity
android:name=".AudioHomeActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:screenOrientation="portrait"/>
android:screenOrientation="portrait" />
<activity
android:name="com.ydl.consultantim.ConsultantAudioHomeActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:screenOrientation="portrait" />
</application>
</manifest>
......@@ -70,7 +70,7 @@ import java.util.concurrent.TimeUnit
/**
* @author jiucheng
* @描述: 声网通话页面
* @描述: 倾诉声网通话页面
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/10/30
......@@ -632,13 +632,15 @@ class AudioHomeActivity :
.subscribeOn(Schedulers.computation())
.take(303)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ var result = it.toFloat() / 2.5f
.subscribe({
var result = it.toFloat() / 2.5f
progress_view.setProgress(result)
if (result >= 100f && !iv_hang_up.isEnabled) {
//挂断按钮可点击
iv_hang_up.isEnabled = true
iv_hang_up.setImageResource(R.drawable.audioim_img_hang_up)
}},{},{})
}
}, {}, {})
//开始60s等待倒计时
waitDisposable = Observable.interval(0, 100, TimeUnit.MILLISECONDS)
......@@ -1139,7 +1141,7 @@ class AudioHomeActivity :
ModularServiceManager.provide(IUserService::class.java).getUserInfo()?.uid!!
var payLoad = PayLoad(channelId ?: "0", time, uid, "1", "999", message)
var connectException = ConnectExceptionCommand(time + zhu, "2", "99", payLoad)
getPresenter().connectException(connectException)
YDLavManager.instances.uploadException(connectException)
}
......
......@@ -9,6 +9,10 @@ import com.ydl.ydl_av.messge_service.callback.InitListener
import com.ydl.ydl_av.messge_service.callback.LoginCallback
import com.ydl.ydl_av.messge_service.request.LoginParam
import com.ydl.audioim.http.AudioApiRequestUtil
import com.ydl.audioim.http.command.ConnectExceptionCommand
import com.ydl.ydl_av.messge_service.callback.CallListener
import com.ydl.ydl_av.messge_service.response.CallLocalResponse
import com.ydl.ydl_av.messge_service.response.CallRemoteResponse
import com.ydl.ydlcommon.utils.LogUtil
import com.ydl.ydlcommon.utils.log.LogHelper
import io.reactivex.android.schedulers.AndroidSchedulers
......@@ -32,6 +36,71 @@ class YDLavManager {
fun init(context: Context,appId:String){
YDLRTMClient.instances.init(context,appId,listener)
//设置回调
setCallback()
}
fun setCallback() {
YDLRTMClient.instances.setCallListener(object : CallListener {
override fun onCallRecivedByPeer(response: CallLocalResponse?) {
//返回给主叫:被叫已收到呼叫邀请
com.yidianling.common.tools.LogUtil.e("[agora]${response?.calleeId}已收到呼叫邀请,频道号${response?.ChannelId}")
}
override fun onCallAccepted(response: CallLocalResponse?, msg: String?) {
//返回给主叫
com.yidianling.common.tools.LogUtil.e("[agora]${response?.calleeId}已接收呼叫邀请")
}
override fun onCallRefused(response: CallLocalResponse?, msg: String?) {
//返回给主叫
com.yidianling.common.tools.LogUtil.e("[agora]${response?.calleeId}已拒绝呼叫邀请")
}
override fun onCallCanceled(response: CallLocalResponse?) {
//返回给主叫
com.yidianling.common.tools.LogUtil.e("[agora]主叫已取消呼叫邀请")
}
override fun onCallFailure(response: CallLocalResponse?, errorCode: Int) {
//返回给主叫
com.yidianling.common.tools.LogUtil.e("[agora]呼叫${response?.calleeId}用户失败:${response?.response}")
}
override fun onRemoteInvitationReceived(response: CallRemoteResponse?) {
//返回给被叫
com.yidianling.common.tools.LogUtil.e("[agora]收到来自${response?.callerId}的呼叫邀请")
receivedCall(response?.content)
}
override fun onRemoteInvitationAccepted(response: CallRemoteResponse?) {
//返回给被叫
com.yidianling.common.tools.LogUtil.e("[agora]接受来自${response?.callerId}的呼叫成功")
}
override fun onRemoteInvitationRefused(response: CallRemoteResponse?) {
//返回给被叫
com.yidianling.common.tools.LogUtil.e("[agora]已拒绝来自${response?.callerId}的呼叫")
}
override fun onRemoteInvitationCanceled(response: CallRemoteResponse?) {
//返回给被叫
com.yidianling.common.tools.LogUtil.e("[agora]主叫${response?.callerId}已取消呼叫邀请")
closePage(true)
}
override fun onRemoteInvitationFailure(response: CallRemoteResponse?, errorCode: Int) {
//返回给被叫
com.yidianling.common.tools.LogUtil.e("[agora]来自主叫${response?.callerId}的呼叫邀请进程失败:${response?.response}")
//关闭页面
closePage(true)
}
override fun onOtherMsg(error: String?) {
com.yidianling.common.tools.LogUtil.e("[agora]其它消息:${error}")
}
})
}
@SuppressLint("CheckResult")
......@@ -86,6 +155,22 @@ class YDLavManager {
}
/**
* RTM登录异常,上传错误日志 msg
* 声网出现异常,上传错误日志 connectException
*/
@SuppressLint("CheckResult")
fun uploadException(connectException: ConnectExceptionCommand) {
AudioApiRequestUtil.connectException(connectException)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
}, {
com.yidianling.common.tools.LogUtil.e("agora", "声网上传异常与错误日志接口调用失败:" + it.message)
})
}
/**
* 实时消息全局监听
*/
private val listener = object :InitListener{
......
......@@ -71,11 +71,6 @@ interface IAudioHomeActivityContract {
*/
// fun connectFinish(param: ConnectFinishCommand)
/**
* 通话异常
*/
fun connectException(param: ConnectExceptionCommand)
/**
* 通知服务端发送推送
......
......@@ -2,6 +2,7 @@ package com.ydl.audioim.http
import com.ydl.audioim.bean.AgoraTokenResponse
import com.ydl.audioim.bean.ConnectBean
import com.ydl.consultantim.bean.ListenTokenBean
import com.ydl.ydlcommon.base.config.YDL_DOMAIN
import com.ydl.ydlcommon.base.config.YDL_DOMAIN_JAVA
import com.ydl.ydlcommon.data.http.BaseAPIResponse
......@@ -61,4 +62,10 @@ interface AudioNetAPi {
@GET("im/getAgoraToken")
fun getAgoraToken(): Observable<BaseAPIResponse<AgoraTokenResponse>>
//获取token
@FormUrlEncoded
@POST("listen/token")
fun listenToken(@FieldMap map: Map<String, String>): Observable<BaseResponse<ListenTokenBean>>
}
\ No newline at end of file
......@@ -66,20 +66,6 @@ class AudioHomePresenterImpl : BasePresenter<IAudioHomeActivityContract.View, IA
// })
// }
@SuppressLint("CheckResult")
override fun connectException(param: ConnectExceptionCommand) {
mModel.connectException(param)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe {
}
.doAfterTerminate {
}
.subscribe({
}, { e ->
LogUtil.e(e.message)
})
}
/**
* 登录声网
......
package com.ydl.consultantim.bean
/**
* @author yuanWai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/11/9
*/
data class ListenTokenBean(val token : String?,
val expired : String?,
val type : String?)
\ No newline at end of file
package com.ydl.consultantim.command
import com.ydl.ydlcommon.data.http.BaseCommand
/**
* @author jiucheng
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2020/3/19
*/
data class ListenTokenCmd(
/**
* 类别 TOKEN|SIGNAL_TOKEN
*/
var type: String? = null,
/**
* 账号(就是uid)
* 如果是SIGNAL_TOKEN 则需要传递该参数
*/
var account: String? = null,
/**
* 频道ID
*/
var channelId: String? = null,
/**
* 过期时间
*/
var expired: String? = null
) : BaseCommand()
\ No newline at end of file
package com.ydl.consultantim.contract
import com.ydl.ydl_av.chat.bean.AudioMessageBean
import com.ydl.ydlcommon.mvp.base.IModel
import com.ydl.ydlcommon.mvp.base.IPresenter
import com.ydl.ydlcommon.mvp.base.IView
/**
* @author jiucheng
* @描述:声网倾诉首页约束类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/10/30
*/
interface IConsultantAudioHomeActivityContract {
interface View : IView {
fun listenStatusPushResponse()
fun channelTokenResponse(token: String?,needJoinChannel: Boolean)
// 执行接听操作
// canExcute是否执行
fun executeCall(canExcute: Boolean)
// 关闭当前页面,并提示用户已挂断
fun executeFinish()
}
interface Presenter : IPresenter<View> {
/**
* 通话开始(更新专家状态)
* @param param 请求参数
* @param isSwitchAxb 是否切换axb
*/
// fun connectStart(param: ConnectStartCommand)
/**
* 通话结束(更新专家状态)
* @param param 请求参数
* @param isSwitchAxb 是否切换axb
*/
// fun connectFinish(param: ConnectFinishCommand)
/**
* 获取频道token
*
*/
fun getChannelToken(mAudioMessageBean: AudioMessageBean?, needJoinChannel: Boolean = true)
/**
* 判断用户是否在频道中
*/
fun userIsInChannel(channelName: String, agoraUid: String)
}
interface Model : IModel {
/**
* 通话开始回调(更新专家状态)
*/
// fun connectStart(param: ConnectStartCommand)
/**
* 通话结束(更新专家状态)
*/
// fun connectFinish(param: ConnectFinishCommand)
}
}
package com.ydl.consultantim.event;
/**
* @author yuanWai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/11/19
*/
public class AudioHomeEvent {
//1.发送停止播放电话铃声和震动
public int type;
public AudioHomeEvent(int type){
this.type = type;
}
}
package com.ydl.consultantim.model
import com.ydl.consultantim.contract.IConsultantAudioHomeActivityContract
/**
* @author jiucheng
* @描述:声网通话页面数据实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/10/30
*/
class ConsultantAudioHomeModelImpl : IConsultantAudioHomeActivityContract.Model {
}
package com.ydl.consultantim.presenter
import com.ydl.consultantim.command.ListenTokenCmd
import com.ydl.consultantim.contract.IConsultantAudioHomeActivityContract
import com.ydl.consultantim.model.ConsultantAudioHomeModelImpl
import com.ydl.ydl_av.chat.bean.AudioMessageBean
import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.mvp.base.BasePresenter
import com.yidianling.user.api.service.IUserService
/**
* @author jiucheng
* @描述:声网通话页面逻辑实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/10/30
*/
class ConsultantAudioHomePresenterImpl :
BasePresenter<IConsultantAudioHomeActivityContract.View, IConsultantAudioHomeActivityContract.Model>(),
IConsultantAudioHomeActivityContract.Presenter {
override fun userIsInChannel(channelName: String, agoraUid: String) {
// RetrofitUtils.userIsInChannel(channelName, agoraUid)
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe({
// view.executeCall(it.data)
// }, {
// LogUtil.e("agora", "专家进入前判断用户是否在频道内接口异常:" + it.message)
// })
}
override fun getChannelToken(msgBean: AudioMessageBean?, needJoinChannel: Boolean) {
if (ModularServiceManager.provide(IUserService::class.java).isLogin()) {
if (null != ModularServiceManager.provide(IUserService::class.java).getUserInfo()) {
val acount =
ModularServiceManager.provide(IUserService::class.java).getUserInfo()?.uid
val tokenParam = ListenTokenCmd()
tokenParam.type = "TOKEN"
tokenParam.account = acount.toString()
tokenParam.uid = acount.toString()
tokenParam.channelId = msgBean?.channelId
//todo
// RetrofitUtils.listenToken(tokenParam)
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe({
// view.channelTokenResponse(it.data.token, needJoinChannel)
// }, {
// RetrofitUtils.handleError(it)
// })
}
}
}
override fun createModel(): IConsultantAudioHomeActivityContract.Model {
return ConsultantAudioHomeModelImpl()
}
}
package com.ydl.consultantim.utils
import android.annotation.SuppressLint
import android.app.KeyguardManager
import android.content.Context
import android.os.PowerManager
/**
* @author jiucheng
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2020/3/19
*/
class ConsultantAudioUtils {
companion object{
/**
* 唤醒手机屏幕并解锁
*/
@SuppressLint("InvalidWakeLockTag")
fun wakeUpAndUnlock(context: Context) { // 获取电源管理器对象
val pm = context.applicationContext
.getSystemService(Context.POWER_SERVICE) as PowerManager
val screenOn = pm.isScreenOn
if (!screenOn) { // 获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是LogCat里用的Tag
val wl = pm.newWakeLock(
PowerManager.ACQUIRE_CAUSES_WAKEUP or
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright"
)
wl.acquire(10000) // 点亮屏幕
wl.release() // 释放
}
// 屏幕解锁
val keyguardManager =context.applicationContext
.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val keyguardLock = keyguardManager.newKeyguardLock("unLock")
// 屏幕锁定
keyguardLock.reenableKeyguard()
keyguardLock.disableKeyguard() // 解锁
}
}
}
\ No newline at end of file
package com.ydl.consultantim.utils;
import android.app.Activity;
import android.app.Service;
import android.os.Vibrator;
/**
* @author yuanWai
* @描述:震动工具类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/11/16
*/
public class VibratorUtil {
/**
* final Activity activity :调用该方法的Activity实例 long milliseconds :震动的时长,单位是毫秒
* long[] pattern :自定义震动模式 。数组中数字的含义依次是[静止时长,震动时长,静止时长,震动时长。。。]时长的单位是毫秒
* boolean isRepeat : 是否反复震动,如果是true,反复震动,如果是false,只震动一次
*/
// 一直震动多少秒
public static void vibrate(final Activity activity, long milliseconds) {
Vibrator vib = (Vibrator) activity
.getSystemService(Service.VIBRATOR_SERVICE);
assert vib != null;
vib.vibrate(milliseconds);
}
// 按照我们传进去的数组进行间歇性的震动
public static void vibrate(final Activity activity, long[] pattern,
boolean isRepeat) {
Vibrator vib = (Vibrator) activity
.getSystemService(Service.VIBRATOR_SERVICE);
assert vib != null;
vib.vibrate(pattern, isRepeat ? 1 : -1);
}
// 停止震动
public static void StopVibrate(final Activity activity) {
Vibrator vib = (Vibrator) activity
.getSystemService(Service.VIBRATOR_SERVICE);
assert vib != null;
vib.cancel();
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/platform_color_80353535">
<RelativeLayout
android:id="@+id/rl_head"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="74dp">
<com.ydl.ydlcommon.view.WaveView
android:id="@+id/wave_view"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true" />
<ImageView
android:layout_width="126dp"
android:layout_height="126dp"
android:layout_centerInParent="true"
android:background="@drawable/audioim_head_background" />
<ImageView
android:id="@+id/iv_head"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerInParent="true"
android:scaleType="centerCrop"
android:src="@drawable/audioim_head_place_hold_pic" />
</RelativeLayout>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/rl_head"
android:layout_centerHorizontal="true"
android:layout_marginTop="-20dp"
android:textColor="@color/white"
android:textSize="26sp"
tools:text="用户" />
<!--自定义弹窗-->
<TextView
android:id="@+id/tv_toast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_name"
android:layout_centerHorizontal="true"
android:layout_marginTop="34dp"
android:background="@drawable/audioim_toast_view_background"
android:elevation="6dp"
android:paddingLeft="11dp"
android:paddingTop="4dp"
android:paddingRight="11dp"
android:paddingBottom="4dp"
android:textColor="@color/white"
android:visibility="gone"
tools:text="连接中..."
tools:visibility="visible" />
<!-- 倾诉剩余时间-->
<RelativeLayout
android:id="@+id/rl_remain_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/rl_hang_up"
android:layout_marginBottom="20dp"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:id="@+id/tv_notes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="本次倾诉时间还有"
android:textColor="@color/platform_color_30FFFFFF"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_remain_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_notes"
android:layout_centerHorizontal="true"
android:text="23:23"
android:textColor="@color/white"
android:textSize="20sp" />
</RelativeLayout>
<!--挂断按钮-->
<RelativeLayout
android:id="@+id/rl_hang_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="72dp"
android:layout_marginBottom="18dp"
android:onClick="hangUpClick">
<ImageView
android:id="@+id/iv_hang_up"
android:layout_width="66dp"
android:layout_height="66dp"
android:layout_centerHorizontal="true"
android:src="@drawable/audioim_img_hang_up"
android:visibility="visible" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/iv_hang_up"
android:layout_centerHorizontal="true"
android:layout_marginTop="9dp"
android:text="挂断"
android:textColor="@color/white"
android:textSize="12sp" />
</RelativeLayout>
<!-- 接听按钮-->
<RelativeLayout
android:id="@+id/rl_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="72dp"
android:layout_marginBottom="18dp"
android:onClick="onCall">
<ImageView
android:id="@+id/iv_hands_call"
android:layout_width="66dp"
android:layout_height="66dp"
android:src="@drawable/audioim_audio_home_img_answer" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/iv_hands_call"
android:layout_centerHorizontal="true"
android:layout_marginTop="9dp"
android:text="接听"
android:textColor="@color/white"
android:textSize="12sp" />
</RelativeLayout>
<!-- 免提按钮-->
<RelativeLayout
android:id="@+id/rl_hands_free"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="72dp"
android:layout_marginBottom="18dp"
android:onClick="onSwitchSpeakerphoneClicked"
android:visibility="gone">
<ImageView
android:id="@+id/iv_hands_free"
android:layout_width="66dp"
android:layout_height="66dp"
android:src="@drawable/audioim_img_hands_free_unuse" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/iv_hands_free"
android:layout_centerHorizontal="true"
android:layout_marginTop="9dp"
android:text="免提"
android:textColor="@color/white"
android:textSize="12sp" />
</RelativeLayout>
</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