Commit 596b8160 by 万齐军

Merge branch 'new_dev_4.3.91' into 'feat/qj_new_dev'

# Conflicts:
#   m-audioim/build.gradle
parents d501ad9c 324e576c
......@@ -12,7 +12,8 @@ kapt {
}
android {
compileSdkVersion 28
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
buildToolsVersion rootProject.ext.android["buildToolsVersion"]
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
......@@ -20,8 +21,8 @@ android {
defaultConfig {
applicationId "com.ydl.component"
minSdkVersion 21
targetSdkVersion 28
minSdkVersion rootProject.ext.android["minSdkVersion"]
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
versionCode 1
versionName "1.0"
multiDexEnabled true
......@@ -37,7 +38,7 @@ android {
multiDexEnabled true
ndk {
abiFilters "arm64-v8a" // 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi,arm-v8之类的so会被过滤掉)
abiFilters "arm64-v8a","armeabi-v7a" // 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi,arm-v8之类的so会被过滤掉)
}
}
......@@ -175,14 +176,21 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation(rootProject.ext.dependencies["appcompat-v7"])
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
// kapt rootProject.ext.dependencies["dagger2-compiler"]
api rootProject.ext.dependencies["butterknife"]
kapt rootProject.ext.dependencies["butterknife-compiler"]
implementation(rootProject.ext.dependencies["design"])
implementation(rootProject.ext.dependencies["appcompat-v7"])
implementation(rootProject.ext.dependencies["espresso-core"])
implementation(rootProject.ext.dependencies["okhttp3"])
// TPNS SDK 主工程依赖包
// implementation 'com.tencent.liteav:LiteAVSDK_TRTC:latest.release'
if (true) {
//开发模式
......@@ -221,8 +229,9 @@ dependencies {
implementation project(':m-fm')
implementation modularPublication('com.ydl:m-fm-api')
} else {
implementation project(':ydl-tuicore')
} else {
//发布模式
api 'com.ydl:m-user-module-ydl:0.0.6'
api rootProject.ext.dependencies["ydl-webview"]
......@@ -232,6 +241,9 @@ dependencies {
api(rootProject.ext.dependencies["ydl-platform"]) {
transitive = true
}
api(rootProject.ext.dependencies["ydl-tuicalling"]) {
transitive = true
}
}
......
......@@ -74,7 +74,46 @@
<activity
android:name=".home.HomeActivity"
android:launchMode="singleTask"
android:noHistory="true"></activity>
android:noHistory="true"/>
<activity
android:name=".rtc.MDTLoginActivity"
android:launchMode="singleTask"
android:theme="@style/Theme.AppCompat.NoActionBar" />
<activity
android:name=".rtc.MDTMainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="com.tencent.liteav.action.portal" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="com.tencent.qcloud"
android:path="/detail"
android:scheme="pushscheme" />
</intent-filter>
<intent-filter>
<action android:name="com.tencent.trtc.tuicalling" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".rtc.ProfileActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.NoActionBar" />
<activity
android:name=".rtc.TUICallingEntranceActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.NoActionBar" />
<activity android:name=".rtc.VideoCallingEnterActivity" />
</application>
</manifest>
\ No newline at end of file
......@@ -20,6 +20,7 @@ import com.ydl.component.music.FragmentContainerActivity
import com.ydl.component.mvp.DemoContract
import com.ydl.component.mvp.DemoPresenter
import com.ydl.component.route.PlatformTempCommonRouteImpl
import com.ydl.component.rtc.MDTLoginActivity
import com.ydl.confide.home.ConfideHomeActivity
import com.ydl.media.audio.PlayService
import com.ydl.ydlcommon.modular.ModularServiceManager
......@@ -83,6 +84,11 @@ class MainActivity : BaseLceActivity<DemoContract.View, DemoContract.Presenter>(
bindService()
reLoadData()
requestPermission()
bt_mdt.setOnClickListener {
val intent = Intent(this, MDTLoginActivity::class.java)
startActivity(intent)
}
tv_user.setOnClickListener {
reLoadData()
}
......
......@@ -9,6 +9,7 @@ import android.webkit.WebView;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.meituan.android.walle.WalleChannelReader;
import com.tencent.qcloud.tuicore.calling.trtccalling.model.TRTCCalling;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
import com.umeng.socialize.PlatformConfig;
......@@ -21,6 +22,7 @@ import com.ydl.ydlcommon.router.YdlCommonRouterManager;
import com.ydl.ydlcommon.utils.AppProgressUtils;
import com.ydl.ydlcommon.utils.Utils;
import com.yidianling.common.tools.LogUtil;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.course.lifeCallback.CoursePlayLifecycle;
......@@ -61,6 +63,23 @@ public class ComponentTestApp extends BaseApp {
registerActivityLifecycleCallbacks(new CoursePlayLifecycle());
Fresco.initialize(this);
TRTCCalling.sharedInstance(this).setMdtCallBack(new TRTCCalling.MdtCallBack() {
@Override
public void onReceiveNewInvitation(String roomId) {
ToastUtil.toastShort("电话邀请"+roomId);
}
@Override
public void onInviteeAccepted(String roomId) {
ToastUtil.toastShort("接受邀请"+roomId);
}
@Override
public void onInviteeRejected(String roomId) {
ToastUtil.toastShort("拒绝邀请"+roomId);
}
});
}
private void initUmeng() {
......
......@@ -21,9 +21,9 @@ import java.util.List;
public final class DemoGlobalConfig implements IConfigModule {
String APP_DOMAIN = "https://api.github.com/";
// public static String appEnv = YDLConstants.ENV_AUTO_TEST;
// public static String appEnv = YDLConstants.ENV_TEST;
public static String appEnv = YDLConstants.ENV_TEST;
// public static String appEnv = YDLConstants.ENV_NEW_TEST;//配置未上传到maven库
public static String appEnv = YDLConstants.ENV_PROD;
// public static String appEnv = YDLConstants.ENV_PROD;
@Override
public void injectAppLifecycle(@NotNull Context context, @NotNull List<IAppLifecycles> lifecycles) {
lifecycles.add(new DemoAppLifecycles());
......
package com.ydl.component.rtc
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.blankj.utilcode.util.ToastUtils
import com.tencent.imsdk.v2.*
import com.tencent.qcloud.tuicore.TUILogin
import com.tencent.qcloud.tuicore.calling.basic.UserModel
import com.tencent.qcloud.tuicore.calling.basic.UserModelManager
import com.ydl.component.R
import com.ydl.component.rtc.bean.UserSigResponse
import com.ydl.component.rtc.http.MDTHttpImpl.Companion.getInstance
import com.ydl.ydlcommon.modular.ModularServiceManager.provide
import com.yidianling.common.tools.ToastUtil
import com.yidianling.user.api.bean.UserResponseBean
import com.yidianling.user.api.service.IUserService
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.util.*
class MDTLoginActivity : AppCompatActivity() {
private var mEditUserId: EditText? = null
private var mButtonLogin: Button? = null
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
initStatusBar()
initView()
}
private fun initView() {
mEditUserId = findViewById<View>(R.id.et_userId) as EditText
initButtonLogin()
}
private fun initButtonLogin() {
mButtonLogin = findViewById<View>(R.id.tv_login) as Button
mButtonLogin!!.setOnClickListener {
getSigin()
}
}
@SuppressLint("CheckResult")
private fun getSigin() {
var user = provide(
IUserService::class.java
).getUserInfo()
val uid = user?.uid
mEditUserId!!.setText(uid)
val userId = mEditUserId!!.text.toString().trim { it <= ' ' }
if (TextUtils.isEmpty(userId)) {
Toast.makeText(this, R.string.user_id_is_empty, Toast.LENGTH_SHORT).show()
return
}
val manager = UserModelManager.getInstance()
val userModel = manager.userModel
uid?.let {uid ->
getInstance().getSecret(UserSigResponse(uid))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ response ->
val data = response.data
if ("200" == response.code) {
userModel.appId = Integer.valueOf(data.appId)
userModel.phone = userId
userModel.userId = userId
userModel.userSig = data.userSig
userModel.userAvatar =user?.head
userModel.userName =user?.nick_name
manager.userModel = userModel
login(userModel)
} else {
ToastUtil.toastShort(response.msg)
}
}, { error ->
ToastUtil.toastShort(error.message)
})
}
}
private fun login(userModel: UserModel) {
val config = V2TIMSDKConfig()
config.logLevel = V2TIMSDKConfig.V2TIM_LOG_DEBUG
TUILogin.init(this, userModel.appId, null, object : V2TIMSDKListener() {
override fun onKickedOffline() {}
override fun onUserSigExpired() {}
})
TUILogin.login(userModel.userId, userModel.userSig, object : V2TIMCallback {
override fun onError(code: Int, msg: String) {
ToastUtils.showLong("登录IM失败,所有功能不可用[%d]%s", code, msg)
Log.d(TAG, "login fail code: $code msg:$msg")
}
override fun onSuccess() {
Log.d(TAG, "login onSuccess")
userInfo
}
})
}//如果用户信息不为空,则直接进入主界面//如果用户名和头像为空,则跳转设置界面进行设置
//先查询用户是否存在
private val userInfo: Unit
private get() {
val manager = UserModelManager.getInstance()
val userModel = manager.userModel
//先查询用户是否存在
val userIdList: MutableList<String> = ArrayList()
userIdList.add(userModel.userId)
Log.d(TAG, "setUserInfo: userIdList = $userIdList")
V2TIMManager.getInstance()
.getUsersInfo(userIdList, object : V2TIMValueCallback<List<V2TIMUserFullInfo>?> {
override fun onError(code: Int, msg: String) {
Log.e(TAG, "get group info list fail, code:$code msg: $msg")
}
override fun onSuccess(resultList: List<V2TIMUserFullInfo>?) {
if (resultList == null || resultList.isEmpty()) {
return
}
val result = resultList[0]
val userName = result.nickName
val userAvatar = result.faceUrl
Log.d(TAG, "onSuccess: userName = $userName , userAvatar = $userAvatar")
//如果用户名和头像为空,则跳转设置界面进行设置
if (TextUtils.isEmpty(userName) || TextUtils.isEmpty(userAvatar)) {
val intent = Intent(this@MDTLoginActivity, ProfileActivity::class.java)
startActivity(intent)
finish()
} else {
userModel.userAvatar = userAvatar
userModel.userName = userName
manager.userModel = userModel
//如果用户信息不为空,则直接进入主界面
val intent = Intent(this@MDTLoginActivity, MDTMainActivity::class.java)
startActivity(intent)
finish()
}
}
})
}
private fun initStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val window = window
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = Color.TRANSPARENT
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
}
companion object {
private const val TAG = "LoginActivity"
}
}
\ No newline at end of file
package com.ydl.component.rtc;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.blankj.utilcode.util.ToastUtils;
import com.tencent.imsdk.v2.V2TIMCallback;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMUserFullInfo;
import com.tencent.qcloud.tuicore.calling.basic.AvatarConstant;
import com.tencent.qcloud.tuicore.calling.basic.ImageLoader;
import com.tencent.qcloud.tuicore.calling.basic.UserModel;
import com.tencent.qcloud.tuicore.calling.basic.UserModelManager;
import com.ydl.component.R;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ProfileActivity extends AppCompatActivity {
private static final String TAG = "ProfileActivity";
private ImageView mImageAvatar;
private EditText mEditUserName;
private Button mButtonRegister;
private TextView mTvInputTips; //昵称限制提示
private String mAvatarUrl; //用户头像
//自定义随机登录名
private static final int[] CUSTOM_NAME_ARRAY = {
R.string.app_custom_name_1,
R.string.app_custom_name_2,
R.string.app_custom_name_3,
R.string.app_custom_name_4,
R.string.app_custom_name_5,
R.string.app_custom_name_6,
R.string.app_custom_name_7,
R.string.app_custom_name_8,
R.string.app_custom_name_9,
R.string.app_custom_name_10,
R.string.app_custom_name_11,
R.string.app_custom_name_12,
};
private void startMainActivity() {
Intent intent = new Intent();
intent.addCategory("android.intent.category.DEFAULT");
intent.setAction("com.tencent.liteav.action.portal");
startActivity(intent);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_profile);
initStatusBar();
initView();
}
private void initView() {
mImageAvatar = (ImageView) findViewById(R.id.iv_user_avatar);
mEditUserName = (EditText) findViewById(R.id.et_user_name);
mButtonRegister = (Button) findViewById(R.id.tv_register);
mTvInputTips = (TextView) findViewById(R.id.tv_tips_user_name);
String[] avatarArr = AvatarConstant.USER_AVATAR_ARRAY;
int index = new Random().nextInt(avatarArr.length);
mAvatarUrl = avatarArr[index];
ImageLoader.loadImage(this, mImageAvatar, mAvatarUrl, R.mipmap.ic_avatar);
mButtonRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setProfile();
}
});
int customNameIndex = new Random().nextInt(CUSTOM_NAME_ARRAY.length);
mEditUserName.setText(getString(CUSTOM_NAME_ARRAY[customNameIndex]));
String text = mEditUserName.getText().toString();
if (!TextUtils.isEmpty(text)) {
mEditUserName.setSelection(text.length());
}
mEditUserName.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence text, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence text, int start, int before, int count) {
mButtonRegister.setEnabled(text.length() != 0);
String editable = mEditUserName.getText().toString();
//匹配字母,数字,中文,下划线,以及限制输入长度为2-20.
Pattern p = Pattern.compile("^[a-z0-9A-Z\\u4e00-\\u9fa5\\_]{2,20}$");
Matcher m = p.matcher(editable);
if (!m.matches()) {
mTvInputTips.setTextColor(getResources().getColor(R.color.color_input_no_match));
} else {
mTvInputTips.setTextColor(getResources().getColor(R.color.text_color_hint));
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
private void setProfile() {
final String userName = mEditUserName.getText().toString().trim();
if (TextUtils.isEmpty(userName)) {
ToastUtils.showLong(getString(R.string.app_hint_user_name));
return;
}
String reg = "^[a-z0-9A-Z\\u4e00-\\u9fa5\\_]{2,20}$";
if (!userName.matches(reg)) {
mTvInputTips.setTextColor(getResources().getColor(R.color.color_input_no_match));
return;
}
mTvInputTips.setTextColor(getResources().getColor(R.color.text_color_hint));
V2TIMUserFullInfo v2TIMUserFullInfo = new V2TIMUserFullInfo();
v2TIMUserFullInfo.setFaceUrl(mAvatarUrl);
v2TIMUserFullInfo.setNickname(userName);
V2TIMManager.getInstance().setSelfInfo(v2TIMUserFullInfo, new V2TIMCallback() {
@Override
public void onError(int code, String desc) {
Log.e(TAG, "set profile failed errorCode : " + code + " errorMsg : " + desc);
//头像和昵称设置失败,也可以进入到主界面(头像和昵称都用默认值),不影响功能
ToastUtils.showLong(getString(R.string.app_toast_failed_to_set, desc));
startMainActivity();
finish();
}
@Override
public void onSuccess() {
Log.i(TAG, "set profile success.");
ToastUtils.showLong(getString(R.string.app_toast_register_success_and_logging_in));
//成功后保存用户数据
UserModel userModel = UserModelManager.getInstance().getUserModel();
userModel.userName = userName;
userModel.userAvatar = mAvatarUrl;
UserModelManager.getInstance().setUserModel(userModel);
startMainActivity();
finish();
}
});
}
private void initStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
}
package com.ydl.component.rtc;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.tencent.qcloud.tuicore.calling.videocall.Constant;
import com.tencent.qcloud.tuicore.calling.videocall.VideoCallingActivity;
import com.ydl.component.R;
/**
* TRTC视频通话的入口页面(可以设置房间id和用户id)
*
* - 可跳转TRTC视频通话页面{@link VideoCallingActivity}
*/
/**
* Video Call Entrance View (set room ID and user ID)
*
* - Direct to the video call view: {@link VideoCallingActivity}
*/
public class VideoCallingEnterActivity extends AppCompatActivity {
private EditText mEditInputUserId;
private EditText mEditInputRoomId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videocall_activit_enter);
mEditInputUserId = findViewById(R.id.et_input_username);
mEditInputRoomId = findViewById(R.id.et_input_room_id);
findViewById(R.id.btn_enter_room).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startEnterRoom();
}
});
findViewById(R.id.rl_entrance_main).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hideInput();
}
});
findViewById(R.id.iv_back).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
mEditInputRoomId.setText("1256732");
String time = String.valueOf(System.currentTimeMillis());
String userId = time.substring(time.length() - 8);
mEditInputUserId.setText(userId);
}
private void startEnterRoom() {
if (TextUtils.isEmpty(mEditInputUserId.getText().toString().trim())
|| TextUtils.isEmpty(mEditInputRoomId.getText().toString().trim())) {
Toast.makeText(VideoCallingEnterActivity.this, "房间号和用户名不能为空", Toast.LENGTH_LONG).show();
return;
}
Intent intent = new Intent(VideoCallingEnterActivity.this, VideoCallingActivity.class);
intent.putExtra(Constant.ROOM_ID, mEditInputRoomId.getText().toString().trim());
intent.putExtra(Constant.USER_ID, mEditInputUserId.getText().toString().trim());
startActivity(intent);
}
protected void hideInput() {
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
View v = getWindow().peekDecorView();
if (null != v) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
}
package com.ydl.component.rtc.bean
/**
* 获取用户密钥
* */
data class UserSigBean(
var appId: String,
var region: String,
var secretId: String,
var userSig: String
)
package com.ydl.component.rtc.bean
/**
* @Author: 刘鹏
* @Description:
* @CreateDate: 2022/4/15 16:37
* -------------------------------
* @UpdateUser:
* @UpdateDate: 2022/4/15 16:37
* @UpdateRemark:
* @Version:
*/
class UserSigResponse(var key: String, var channel: String = "tencent")
\ No newline at end of file
package com.ydl.component.rtc.debug;
import android.text.TextUtils;
import android.util.Base64;
import org.json.JSONException;
import org.json.JSONObject;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.zip.Deflater;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/*
* Module: GenerateTestUserSig
*
* Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。
* 其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
*
* Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
*
* 本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
* 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
* 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
*
* 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
* 由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
*
* Reference:https://cloud.tencent.com/document/product/269/32688#Server
*/
public class GenerateTestUserSig {
/**
* 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
* <p>
* 进入腾讯云云通信[控制台](https://console.cloud.tencent.com/avc ) 创建应用,即可看到 SDKAppId,
* 它是腾讯云用于区分客户的唯一标识。
*/
public static final int SDKAPPID = 1400646402;
/**
* 签名过期时间,建议不要设置的过短
* <p>
* 时间单位:秒
* 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
*/
private static final int EXPIRETIME = 604800;
/**
* 向后台请求推拉流地址
* <p>
* key:url_push 获取RTMP推流地址
* key:url_play_flv 获取FLV播放地址
*/
public static final String URL_FETCH_PUSH_URL = "PLACEHOLDER";
/**
* 计算签名用的加密密钥,获取步骤如下:
* <p>
* step1. 进入腾讯云云通信[控制台](https://console.cloud.tencent.com/avc ) ,如果还没有应用就创建一个,
* step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
* step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
* <p>
* 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
* 文档:https://cloud.tencent.com/document/product/269/32688#Server
*/
private static final String SECRETKEY = "84ed667420eee66e4d99de8d7f76b40ca6b9f8fffacb885068aaa9493cae7a0a";
/**
* 计算 UserSig 签名
* <p>
* 函数内部使用 HMAC-SHA256 非对称加密算法,对 SDKAPPID、userId 和 EXPIRETIME 进行加密。
*
* @note: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
* <p>
* 本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
* 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
* 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
* <p>
* 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
* 由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
* <p>
* 文档:https://cloud.tencent.com/document/product/269/32688#Server
*/
public static String genTestUserSig(String userId) {
// return GenTLSSignature(SDKAPPID, userId, EXPIRETIME, null, SECRETKEY);
return "eJyrVgrxCdZLrSjILEpVsjIzMLEwMNABi5WlFilZKRnpGShB*MUp2YkFBZkpSlaGJgYGZiZmJgZGEJnMlNS8ksy0TLAGQ2MDS1NjSzNLmLbMdKCoiVNEmHl6lpt2kEtVoUdaUl5iWGSgV3JuuIVjiYebRZ6XdklEpktquFtJpC1UY0lmLtBFhmYmlpaGppbGprUAOugw0Q__";
}
/**
* 生成 tls 票据
*
* @param sdkappid 应用的 appid
* @param userId 用户 id
* @param expire 有效期,单位是秒
* @param userbuf 默认填写null
* @param priKeyContent 生成 tls 票据使用的私钥内容
* @return 如果出错,会返回为空,或者有异常打印,成功返回有效的票据
*/
private static String GenTLSSignature(long sdkappid, String userId, long expire, byte[] userbuf, String priKeyContent) {
if (TextUtils.isEmpty(priKeyContent)) {
return "";
}
long currTime = System.currentTimeMillis() / 1000;
JSONObject sigDoc = new JSONObject();
try {
sigDoc.put("TLS.ver", "2.0");
sigDoc.put("TLS.identifier", userId);
sigDoc.put("TLS.sdkappid", sdkappid);
sigDoc.put("TLS.expire", expire);
sigDoc.put("TLS.time", currTime);
} catch (JSONException e) {
e.printStackTrace();
}
String base64UserBuf = null;
if (null != userbuf) {
base64UserBuf = Base64.encodeToString(userbuf, Base64.NO_WRAP);
try {
sigDoc.put("TLS.userbuf", base64UserBuf);
} catch (JSONException e) {
e.printStackTrace();
}
}
String sig = hmacsha256(sdkappid, userId, currTime, expire, priKeyContent, base64UserBuf);
if (sig.length() == 0) {
return "";
}
try {
sigDoc.put("TLS.sig", sig);
} catch (JSONException e) {
e.printStackTrace();
}
Deflater compressor = new Deflater();
compressor.setInput(sigDoc.toString().getBytes(Charset.forName("UTF-8")));
compressor.finish();
byte[] compressedBytes = new byte[2048];
int compressedBytesLength = compressor.deflate(compressedBytes);
compressor.end();
return new String(base64EncodeUrl(Arrays.copyOfRange(compressedBytes, 0, compressedBytesLength)));
}
private static String hmacsha256(long sdkappid, String userId, long currTime, long expire, String priKeyContent, String base64Userbuf) {
String contentToBeSigned = "TLS.identifier:" + userId + "\n"
+ "TLS.sdkappid:" + sdkappid + "\n"
+ "TLS.time:" + currTime + "\n"
+ "TLS.expire:" + expire + "\n";
if (null != base64Userbuf) {
contentToBeSigned += "TLS.userbuf:" + base64Userbuf + "\n";
}
try {
byte[] byteKey = priKeyContent.getBytes("UTF-8");
Mac hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(byteKey, "HmacSHA256");
hmac.init(keySpec);
byte[] byteSig = hmac.doFinal(contentToBeSigned.getBytes("UTF-8"));
return new String(Base64.encode(byteSig, Base64.NO_WRAP));
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
private static byte[] base64EncodeUrl(byte[] input) {
byte[] base64 = new String(Base64.encode(input, Base64.NO_WRAP)).getBytes();
for (int i = 0; i < base64.length; ++i) {
switch (base64[i]) {
case '+':
base64[i] = '*';
break;
case '/':
base64[i] = '-';
break;
case '=':
base64[i] = '_';
break;
default:
break;
}
}
return base64;
}
}
package com.ydl.component.rtc.http
import com.ydl.component.rtc.bean.UserSigBean
import com.ydl.component.rtc.bean.UserSigResponse
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import io.reactivex.Observable
interface MDTHttp {
fun getSecret(bean: UserSigResponse): Observable<BaseAPIResponse<UserSigBean>>
}
\ No newline at end of file
package com.ydl.component.rtc.http
import com.google.gson.Gson
import com.ydl.component.rtc.bean.UserSigBean
import com.ydl.component.rtc.bean.UserSigResponse
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import com.ydl.ydlnet.YDLHttpUtils
import io.reactivex.Observable
import okhttp3.MediaType
import okhttp3.RequestBody
class MDTHttpImpl :MDTHttp {
private var mdtService: MDTService? = null
object Holder {
val INSTANCE = MDTHttpImpl()
}
companion object {
fun getInstance(): MDTHttpImpl {
return Holder.INSTANCE
}
}
private fun getMdtService(): MDTService {
if (mdtService == null) {
mdtService = YDLHttpUtils.obtainApi(MDTService::class.java)
}
return mdtService!!
}
//获取登录信息
override fun getSecret(bean: UserSigResponse): Observable<BaseAPIResponse<UserSigBean>> {
val str = Gson().toJson(bean)
val body: RequestBody =
RequestBody.create(MediaType.parse("application/json; charset=utf-8"), str)
return getMdtService().getSecret(body)
}
}
\ No newline at end of file
package com.ydl.component.rtc.http
import com.ydl.component.rtc.bean.UserSigBean
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 io.reactivex.Observable
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.Headers
import retrofit2.http.POST
interface MDTService {
//获取用户密钥
@POST("video/secret")
@Headers(
YDL_DOMAIN + YDL_DOMAIN_JAVA,
"Content-Type:application/json"
)
fun getSecret(@Body body: RequestBody): Observable<BaseAPIResponse<UserSigBean>>
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/color_blue" />
<corners android:radius="20dp" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#F4F5F9" />
<corners android:radius="26dp" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_white" />
<corners android:radius="10dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF999999" />
<corners android:radius="15dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true">
<shape android:shape="rectangle"
android:useLevel="false">
<solid android:color="#006EFF" />
<corners android:radius="28dp"/>
<padding android:left="5dp" android:right="5dp" android:top="3dp" android:bottom="3dp"/>
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle"
android:useLevel="false">
<solid android:color="#0F000000" />
<corners android:radius="28dp"/>
<padding android:left="5dp" android:right="5dp" android:top="3dp" android:bottom="3dp"/>
</shape>
</item>
</selector>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#EFEFEF" />
<corners
android:bottomLeftRadius="2dip"
android:bottomRightRadius="2dip"
android:topLeftRadius="2dip"
android:topRightRadius="2dip" />
<stroke
android:width="5px"
android:color="@color/white" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:layout_marginTop="28dp"
android:layout_marginEnd="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_back">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:text="@string/app_name"
android:textColor="@color/color_black"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="@+id/btn_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:background="@android:color/transparent"
android:text="@string/btn_confirm"
android:textColor="@color/black"
android:visibility="gone" />
<ImageButton
android:id="@+id/btn_link"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right|center_vertical"
android:background="@color/color_transparent"
android:padding="10dp"
android:src="@drawable/ic_question_link" />
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:id="@+id/ll_list"
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
android:padding="20dp"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_added_member"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<ListView
android:id="@+id/list_member"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_edit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:background="@drawable/bg_edit_text"
android:padding="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/tv_search"
app:layout_constraintTop_toBottomOf="@+id/ll_list">
<TextView
android:id="@+id/tv_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="ID"
android:textColor="@color/color_black"
app:layout_constraintBaseline_toBaselineOf="@id/et_search_user"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_search_user"
android:layout_width="210dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:background="@null"
android:hint="@string/search_call_hint"
android:imeOptions="actionSearch"
android:inputType="number"
android:maxLength="11"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/color_black"
android:textColorHint="@color/text_color_hint"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@id/cl_edit"
app:layout_constraintLeft_toRightOf="@id/tv_id" />
<ImageView
android:id="@+id/iv_clear_search"
android:layout_width="22dp"
android:layout_height="22dp"
android:background="@drawable/ic_clear_search"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/cl_edit"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/cl_edit" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_search"
android:layout_width="76dp"
android:layout_height="38dp"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_btn_search"
android:gravity="center"
android:text="@string/trtccalling_search"
android:textColor="@color/color_white"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="@id/cl_edit"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/cl_edit" />
<TextView
android:id="@+id/line_seperate"
android:layout_width="3dp"
android:layout_height="12dp"
android:layout_marginTop="21dp"
android:layout_marginEnd="22dp"
android:background="@drawable/bg_line_radius"
app:layout_constraintLeft_toLeftOf="@id/cl_edit"
app:layout_constraintTop_toBottomOf="@id/cl_edit" />
<TextView
android:id="@+id/tv_self_userid"
android:layout_width="wrap_content"
android:layout_height="22dp"
android:layout_marginStart="8dp"
android:layout_marginTop="17dp"
android:text="@string/self_userId"
android:textColor="#333333"
android:textSize="14sp"
app:layout_constraintStart_toEndOf="@id/line_seperate"
app:layout_constraintTop_toBottomOf="@id/cl_edit" />
<LinearLayout
android:id="@+id/ll_contract"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:gravity="center_vertical"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="@id/tv_search"
app:layout_constraintStart_toStartOf="@+id/cl_edit"
app:layout_constraintTop_toBottomOf="@+id/tv_self_userid"
tools:visibility="visible">
<com.tencent.qcloud.tuicore.calling.trtccalling.ui.common.RoundCornerImageView
android:id="@+id/img_avatar"
android:layout_width="44dp"
android:layout_height="44dp"
android:src="@drawable/ic_avatar"
app:trtc_radius="15dp" />
<TextView
android:id="@+id/tv_user_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_weight="1"
android:textColor="@color/color_black"
android:textSize="16sp" />
<Button
android:id="@+id/btn_start_call"
android:layout_width="56dp"
android:layout_height="26dp"
android:background="@drawable/bg_btn_search"
android:gravity="center"
android:text="@string/trtccalling_start_call"
android:textAllCaps="false"
android:textColor="@color/color_white" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_tips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="120dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cl_edit">
<ImageView
android:id="@+id/iv_contacts_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_contacts_search"
app:layout_constraintBottom_toBottomOf="@id/cl_tips"
app:layout_constraintLeft_toLeftOf="@id/cl_tips"
app:layout_constraintRight_toRightOf="@id/cl_tips"
app:layout_constraintTop_toTopOf="@id/cl_tips" />
<TextView
android:id="@+id/tv_contacts_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:layout_marginTop="10dp"
android:text="@string/tips_search"
android:textColor="@color/color_input_normal"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="@id/cl_tips"
app:layout_constraintRight_toRightOf="@id/cl_tips"
app:layout_constraintTop_toBottomOf="@id/iv_contacts_search" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/item_cl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_item_main_list">
<ImageView
android:id="@+id/img_item"
android:layout_width="170dp"
android:layout_height="136dp"
android:layout_marginStart="14dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_audio_call" />
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="34dp"
android:layout_marginEnd="10dp"
android:textColor="@color/color_black"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintLeft_toRightOf="@id/img_item"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="10dp"
android:paddingBottom="20dp"
android:textColor="#666666"
android:textSize="14sp"
app:layout_constraintLeft_toRightOf="@id/img_item"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/bottom_line"
android:layout_width="match_parent"
android:layout_height="25dp"
android:visibility="gone" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="120dp"
android:text="@string/welcome_tips"
android:textColor="@color/color_black"
android:textSize="32sp"
app:layout_constraintBottom_toTopOf="@id/cl_edit"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="30dp"
android:background="@drawable/bg_edit_text"
android:padding="16dp"
app:layout_constraintBottom_toTopOf="@id/tv_login"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<TextView
android:id="@+id/tv_phone_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/user_id"
android:textColor="@color/color_black"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="@id/cl_edit"
app:layout_constraintTop_toTopOf="@id/cl_edit" />
<EditText
android:id="@+id/et_userId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@null"
android:hint="@string/hint_user_id"
android:inputType="number"
android:maxLength="11"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/color_black"
android:textColorHint="@color/color_input_normal"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@id/tv_phone_number"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toRightOf="@id/tv_phone_number"
app:layout_constraintStart_toEndOf="@+id/tv_phone_number" />
</androidx.constraintlayout.widget.ConstraintLayout>
<Button
android:id="@+id/tv_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="@drawable/btn_border"
android:text="@string/btn_login"
android:textColor="@color/color_white"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:text="@string/app_title_register"
android:textColor="@color/color_black"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.tencent.qcloud.tuicore.calling.trtccalling.ui.common.RoundCornerImageView
android:id="@+id/iv_user_avatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="30dp"
android:layout_centerHorizontal="true"
app:trtc_radius="50dp"
android:src="@mipmap/ic_avatar"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title"
tools:ignore="MissingConstraints" />
<EditText
android:id="@+id/et_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="30dp"
android:layout_marginRight="20dp"
android:background="@drawable/bg_edit_text"
android:hint="@string/app_hint_user_name"
android:maxLines="1"
android:padding="20dp"
android:singleLine="true"
android:textColor="@color/color_black"
android:textColorHint="#BBBBBB"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_user_avatar" />
<TextView
android:id="@+id/tv_tips_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:text="@string/app_tips_user_name"
android:textColor="@color/text_color_hint"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_user_name" />
<Button
android:id="@+id/tv_register"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="30dp"
android:layout_marginRight="20dp"
android:background="@drawable/btn_border"
android:text="@string/app_title_register"
android:textColor="@color/color_white"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tips_user_name" />
</androidx.constraintlayout.widget.ConstraintLayout>
......@@ -218,6 +218,14 @@
android:layout_marginRight="10dp"
android:text="我的" />
<Button
android:id="@+id/bt_mdt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="10dp"
android:text="mdt" />
</LinearLayout>
</LinearLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white">
<RelativeLayout
android:id="@+id/rl_title"
android:layout_width="match_parent"
android:layout_height="42dp"
android:layout_marginTop="28dp"
android:background="@color/color_white">
<TextView
android:id="@+id/main_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/color_black"
android:textSize="18sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/img_logout"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:layout_marginStart="15dp"
android:src="@mipmap/ic_avatar"
android:visibility="gone" />
<TextView
android:id="@+id/tv_login_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:text="@string/app_login_out"
android:textColor="@color/color_black"
android:textSize="16sp" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/rl_title"
android:background="@color/color_main_bg"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="270dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/bg_item_main_list">
<TextView
android:id="@+id/tv_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:text="aa"
android:textColor="@color/color_main_text"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view_divide"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="20dp"
android:background="@color/color_line"
app:layout_constraintTop_toBottomOf="@id/tv_message" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_button_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/view_divide">
<Button
android:id="@+id/btn_cancel"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@android:color/transparent"
android:gravity="center"
android:text="@string/btn_confirm"
android:textColor="@color/color_blue"
android:textSize="17sp"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:padding="5dp">
<com.tencent.qcloud.tuicore.calling.trtccalling.ui.common.RoundCornerImageView
android:id="@+id/img_avatar"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/ic_avatar"
app:trtc_radius="12dp" />
<TextView
android:id="@+id/tv_user_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_weight="1"
android:textColor="@color/color_black"
android:textSize="16sp" />
<Button
android:id="@+id/btn_remove"
android:layout_width="56dp"
android:layout_height="26dp"
android:background="@drawable/bg_btn_search"
android:gravity="center"
android:text="@string/app_remove"
android:textAllCaps="false"
android:textColor="@color/color_white" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="270dp"
android:layout_height="142dp"
android:layout_gravity="center"
android:background="@drawable/bg_edit_text">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:text="@string/dialog_log_out"
android:textColor="@color/color_black"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view_divide"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="43dp"
android:background="@color/text_color_hint"
app:layout_constraintBottom_toBottomOf="parent" />
<View
android:layout_width="1dp"
android:layout_height="43dp"
android:background="@color/text_color_hint"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_button_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent">
<Button
android:id="@+id/btn_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:text="@string/btn_cancel"
android:textColor="@color/color_blue"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/cl_button_panel"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="@id/cl_button_panel"
app:layout_constraintRight_toLeftOf="@+id/btn_sure" />
<Button
android:id="@+id/btn_sure"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:text="@string/btn_confirm"
android:textColor="@color/color_blue"
android:textSize="17sp"
app:layout_constraintBottom_toBottomOf="@id/cl_button_panel"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@id/btn_cancel"
app:layout_constraintRight_toRightOf="@id/cl_button_panel" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
......@@ -9,8 +9,8 @@
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin">
android:paddingLeft="16dp"
android:paddingRight="16dp">
<TextView
android:id="@+id/tv_current_time"
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_entrance_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#1B1B1B">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
android:background="@drawable/common_ic_back" />
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="15dp"
android:gravity="center_horizontal"
android:text="TRTC 视频通话示例"
android:textColor="@android:color/white"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_room_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginLeft="60dp"
android:layout_marginTop="100dp"
android:layout_marginRight="60dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请输入房间号(必填项)"
android:textColor="@android:color/white" />
<EditText
android:id="@+id/et_input_room_id"
android:layout_width="match_parent"
android:layout_height="34dp"
android:layout_marginTop="5dp"
android:background="@drawable/common_edit_bg"
android:inputType="number" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ll_room_info"
android:layout_centerHorizontal="true"
android:layout_marginLeft="60dp"
android:layout_marginTop="30dp"
android:layout_marginRight="60dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请输入用户名(必填项)"
android:textColor="@android:color/white" />
<EditText
android:id="@+id/et_input_username"
android:layout_width="match_parent"
android:layout_height="34dp"
android:layout_marginTop="5dp"
android:background="@drawable/common_edit_bg" />
</LinearLayout>
<Button
android:id="@+id/btn_enter_room"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_margin="60dp"
android:background="@drawable/common_button_bg"
android:text="进入房间"
android:textColor="@android:color/white" />
</RelativeLayout>
\ No newline at end of file
......@@ -12,7 +12,17 @@
<color name="blue">#2196F3</color>
<color name="grey">#9E9E9E</color>
<color name="color_white">#ffffff</color>
<color name="color_black">#000000</color>
<color name="color_transparent">#00000000</color>
<color name="text_color_hint">#BBBBBB</color>
<color name="color_blue">#006EFF</color>
<color name="color_bg_dialog">#66000000</color>
<color name="color_line">#DDDDDD</color>
<color name="color_input_normal">#BBBBBB</color>
<color name="color_input_no_match">#FA585E</color>
<color name="color_main_bg">#F1F3F8</color>
<color name="color_main_text">#333333</color>
<!-- ============ 标准颜色 ============ -->
<!--主题色 - 用于TabBar、突出文字、按钮和icon-->
......
......@@ -4,4 +4,65 @@
<string name="mode_loop">列表循环</string>
<string name="mode_shuffle">随机播放</string>
<string name="mode_one">单曲循环</string>
<string name="app_toast_login_success">登录成功</string>
<string name="app_toast_login_fail">登录IM失败,所有功能不可用[%d]%s</string>
<string name="working">正在运行中</string>
<string name="self_userId">您的userId:</string>
<string name="tips_search">搜索添加已注册用户\n\t\t\t以发起通话</string>
<string name="toast_video_call">视频呼叫:%s</string>
<string name="toast_voice_call">语音呼叫:%s</string>
<string name="toast_not_call_myself">不能呼叫自己</string>
<string name="call_self_format">您的userId: %s</string>
<string name="audio_call">语音通话</string>
<string name="video_call">视频通话</string>
<string name="btn_cancel">取消</string>
<string name="btn_confirm">确定</string>
<string name="search_call_hint">搜索 userId</string>
<string name="user_id">用户名</string>
<string name="hint_user_id">请输入登录的userId</string>
<string name="btn_login">登录</string>
<string name="welcome_tips">欢迎使用\n腾讯云实时音视频</string>
<string name="dialog_log_out">确定要退出登录吗?</string>
<string name="user_sig_expired">您的用户签名信息已过期,请重新登录</string>
<string name="user_id_is_empty">userId 不能为空</string>
<string name="app_title_register">注册</string>
<string name="app_text_user_name">用户名</string>
<string name="app_hint_user_name">请输入用户名</string>
<string name="app_tips_user_name">仅限中文、字母、数字和下划线,2–20个字</string>
<string name="app_toast_register_success_and_logging_in">注册成功</string>
<string name="app_toast_failed_to_set">设置失败: %s</string>
<string name="app_item_multi_audio_call">多人语音通话</string>
<string name="app_item_multi_video_call">多人视频通话</string>
<string name="app_added_member">已添加成员</string>
<string name="app_toast_no_member">无通话成员</string>
<string name="app_toast_multi_call_num_exceed">添加失败,人数超出限制</string>
<string name="app_toast_user_added">用户已添加</string>
<string name="app_tips_search">搜索添加已注册用户\n\t\t\t以发起通话</string>
<string name="app_self_userid">您的ID:</string>
<string name="app_search">搜索</string>
<string name="app_start_call">呼叫</string>
<string name="app_user_not_exist">用户不存在</string>
<string name="app_add">添加</string>
<string name="app_remove">移除</string>
<string name="app_tv_voice_call_tips">丢包率>70%可正常语音通话</string>
<string name="app_tv_video_call_tips">丢包率>50%可正常视频通话</string>
<string name="app_login_out">退出登录</string>
<string name="app_permission_hint">为了应用在后台时响应通话请求,请到设置中打开应用“后台拉起界面”权限</string>
<!--自定义随机登录名-->
<string name="app_custom_name_1">路飞</string>
<string name="app_custom_name_2">山治</string>
<string name="app_custom_name_3">娜美</string>
<string name="app_custom_name_4">乌索普</string>
<string name="app_custom_name_5">香克斯</string>
<string name="app_custom_name_6">弗兰奇</string>
<string name="app_custom_name_7">罗宾</string>
<string name="app_custom_name_8">钢铁侠</string>
<string name="app_custom_name_9">蜘蛛侠</string>
<string name="app_custom_name_10">乔巴</string>
<string name="app_custom_name_11">鸣人</string>
<string name="app_custom_name_12">艾斯</string>
</resources>
<resources>
<!-- Base application theme. -->
<style name="logoutDialogStyle" parent="@android:style/Theme.Holo.Dialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowCloseOnTouchOutside">true</item>
<item name="android:windowBackground">@color/color_bg_dialog</item>
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
</resources>
{
"tpns": {
"access_id": "",
"access_key": ""
},
"com.tencent.trtc": {
"channel": {
"enable": true,
"xiaomi": {
"app_id": "",
"app_key": ""
},
"vivo": {
"app_id": "",
"app_key": ""
},
"oppo": {
"app_id": "",
"app_key": ""
},
"meizu": {
"app_id": "",
"app_key": ""
}
}
},
"debug": true,
"version": "1.3.2.1-release",
"upgrade": false
}
\ No newline at end of file
......@@ -5,10 +5,10 @@ ext {
ydlPublishVersion = [
// -------------- 业务模块 --------------
//第三步 若干
"m-confide" : "0.0.49.64",
"m-consultant" : "0.0.60.11",
"m-confide" : "0.0.49.65",
"m-consultant" : "0.0.60.17",
"m-fm" : "0.0.30.04",
"m-user" : "0.0.62.03",
"m-user" : "0.0.62.04",
"m-home" : "0.0.23.17",
"m-im" : "0.0.21.21",
"m-dynamic" : "0.0.7.35",
......@@ -32,23 +32,26 @@ ext {
"m-dynamic-api" : "0.0.3.71",
//-------------- 功能组件 --------------
//mdt 组件
"ydl-tuicore" : "0.0.22",
// "m-tuicore-ydl" : "0.0.10",
//第一步
"ydl-platform" : "0.0.40.89",
"ydl-platform" : "0.0.40.96",
//第二步 若干
"ydl-webview" : "0.0.38.61",
"ydl-media" : "0.0.21.42",
"ydl-pay" : "0.0.18.19",
"m-audioim" : "0.0.49.29.84",
"m-audioim" : "0.0.49.29.85",
"ydl-flutter-base": "0.0.14.38",
//以下 几乎不会动
"router" : "0.0.1",
"ydl-net" : "0.0.3.92",
"ydl-utils" : "0.0.3.2",
"ydl-net" : "0.0.3.93",
"ydl-utils" : "0.0.3.3",
]
ydl_app = [
appName : "心理咨询壹点灵",
appName : "壹点灵心理咨询",
applicationId: "com.cxzapp.yidianling",
versionName : "4.0.99",
versionCode : 4099,
......@@ -89,10 +92,10 @@ ext {
// -------------- 业务模块 --------------
//第三步 若干
"m-confide" : "0.0.49.64",
"m-consultant" : "0.0.60.11",
"m-confide" : "0.0.49.65",
"m-consultant" : "0.0.60.17",
"m-fm" : "0.0.30.07",
"m-user" : "0.0.62.03",
"m-user" : "0.0.62.04",
"m-home" : "0.0.23.17",
"m-im" : "0.0.21.21",
"m-dynamic" : "0.0.7.35",
......@@ -114,21 +117,23 @@ ext {
"m-im-api" : "0.0.12.23",
"m-dynamic-api" : "0.0.3.71",
//-------------- 功能组件 --------------
//mdt组件
"ydl-tuicore" : "0.0.9",
"m-tuicore-ydl" : "0.0.10",
//第一步
"ydl-platform" : "0.0.40.89",
"ydl-platform" : "0.0.40.96",
//第二步 若干
"ydl-webview" : "0.0.38.61",
"ydl-media" : "0.0.21.42",
"ydl-pay" : "0.0.18.19",
"m-audioim" : "0.0.49.29.84",
"m-audioim" : "0.0.49.29.85",
"ydl-flutter-base": "0.0.14.38",
//以下 几乎不会动
"router" : "0.0.1",
"ydl-net" : "0.0.3.92",
"ydl-utils" : "0.0.3.1",
"ydl-net" : "0.0.3.93",
"ydl-utils" : "0.0.3.3",
]
dependencies = [
......@@ -237,7 +242,7 @@ ext {
"androidanimations" : "com.daimajia.androidanimations:library:2.3@aar",
//友盟统计
"umeng-common" : "com.umeng.umsdk:common:9.3.8",
"umeng-asms" :"com.umeng.umsdk:asms:1.2.2",
"umeng-asms" : "com.umeng.umsdk:asms:1.2.2",
//友盟社会化分享
"umeng-share-core" : "com.umeng.umsdk:share-core:7.1.4",
"umeng-share-qq" : "com.umeng.umsdk:share-qq:7.1.4",
......@@ -282,7 +287,8 @@ ext {
//基础组件 <<--- 先发这个,发完改这里的版本号
"ydl-platform" : "com.ydl:ydl-platform:${ydlCompileVersion["ydl-platform"]}@aar",
"ydl-tuicore" : "com.ydl:ydl-tuicore:${ydlCompileVersion["ydl-tuicore"]}@aar",
"m-tuicore-ydl" : "com.ydl:m-tuicore-ydl:${ydlCompileVersion["m-tuicore-ydl"]}@aar",
//功能组件 <<--- 再发这些,发完改这里的版本号
"ydl-webview" : "com.ydl:ydl-webview:${ydlCompileVersion["ydl-webview"]}@aar",
"ydl-media" : "com.ydl:ydl-media:${ydlCompileVersion["ydl-media"]}@aar",
......
......@@ -810,7 +810,7 @@ class AudioHomeActivity :
* param mRtcEventHandler 事件回调(SDK 通过指定的事件通知应用程序 SDK 的运行事件,如: 加入或离开频道,新用户加入频道等)
*/
voiceManage = YDLVoiceManager(this, BuildConfig.AGORA_APPID, mRtcEventHandler)
voiceManage?.init()
voiceManage!!.init()
}
/**
......
......@@ -70,9 +70,7 @@ class YDLavManager {
fun init(context: Context, appId: String) {
YDLRTMClient.instances.init(context, appId, listener)
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this)
}
EventBus.getDefault().register(this)
//设置回调
setCallback()
......
......@@ -7,13 +7,8 @@ import android.animation.PropertyValuesHolder
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.drm.DrmStore
import android.graphics.Typeface
import android.os.Build
import androidx.core.content.ContextCompat
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.text.TextUtils
import android.view.Gravity
import android.view.View
......@@ -22,6 +17,10 @@ import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.google.android.material.appbar.AppBarLayout
......@@ -391,7 +390,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
private fun initData(mIntent: Intent) {
fromPageType = mIntent.getIntExtra(EXTRA_FROM_PAGE, -1)
initCategory = mIntent.getStringExtra(EXTRA_CATEGORY)?:""
initCategory = mIntent.getStringExtra(EXTRA_CATEGORY) ?: ""
initShowType = mIntent.getIntExtra(EXTRA_SHOW_TYPE, 0)
tv_search_content.text = mIntent.getStringExtra(EXTRA_SEARCH_WORD)
keyWord = mIntent.getStringExtra(EXTRA_CATEGORY_NAME) ?: ""
......@@ -485,7 +484,8 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
val popWidth = RxDeviceTool.getScreenWidth(mContext)
val mWidth = (popWidth - RxImageTool.dp2px(10f)) / hotData.size
for ((index, hot) in hotData!!.withIndex()) {
val tv = View.inflate(mContext, R.layout.consultant_item_filter_online, null) as TextView
val tv =
View.inflate(mContext, R.layout.consultant_item_filter_online, null) as TextView
val textView = tv.tvFree
val params = LinearLayout.LayoutParams(0, RxImageTool.dp2px(22f))
params.weight = 1f
......@@ -644,7 +644,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
}
}
}
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.title.size > 0) {
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.doctorEdu.size + allFilter.title.size > 0) {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_FILTERED)
} else {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_NORMAL)
......@@ -664,7 +664,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
}
}
}
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.title.size > 0) {
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.doctorEdu.size + allFilter.title.size > 0) {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_FILTERED)
} else {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_NORMAL)
......@@ -684,7 +684,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
}
}
}
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.title.size > 0) {
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.doctorEdu.size + allFilter.title.size > 0) {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_FILTERED)
} else {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_NORMAL)
......@@ -704,7 +704,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
}
}
}
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.title.size > 0) {
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.doctorEdu.size + allFilter.title.size > 0) {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_FILTERED)
} else {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_NORMAL)
......@@ -1011,6 +1011,9 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
tempFilter.showType = allFilter.showType
tempFilter.ages.clear()
tempFilter.ages.addAll(allFilter.ages)
//学历
tempFilter.doctorEdu.clear()
tempFilter.doctorEdu.addAll(allFilter.doctorEdu)
tempFilter.enquiries.clear()
tempFilter.enquiries.addAll(allFilter.enquiries)
// 擅长人群添加数据
......@@ -1026,7 +1029,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
filterPopupWindow.setOnDismissListener {
// viewDim.visibility = View.INVISIBLE
viewDim_filter.visibility = View.GONE
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.title.size > 0 || !TextUtils.isEmpty(
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.doctorEdu.size + allFilter.title.size > 0 || !TextUtils.isEmpty(
allFilter.priceRanges?.minPrice
) || !TextUtils.isEmpty(allFilter.priceRanges?.maxPrice)
) {
......@@ -1052,14 +1055,18 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
//筛选确认回调
override fun onFilterConfirmed() {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_OPEN)
LogUtil.d("filter: " + tempFilter.showType.value + "," + tempFilter.enquiries.map { it.value }
.joinToString(",") + "," + tempFilter.ages.map { it.value }
.joinToString(",") + "," + tempFilter.others.map { it.value }.joinToString(","))
LogUtil.d("filter: " + tempFilter.showType.value + ","
+ tempFilter.enquiries.map { it.value }.joinToString(",") + ","
+ tempFilter.ages.map { it.value }.joinToString(",") + ","
+ tempFilter.others.map { it.value }.joinToString(",")+ ","
+ tempFilter.doctorEdu.map { it.value }.joinToString(","))
props1.put(
"filtrate_second",
tempFilter.showType.value + "," + tempFilter.enquiries.map { it.value }
.joinToString(",") + "," + tempFilter.ages.map { it.value }
.joinToString(",") + "," + tempFilter.others.map { it.value }.joinToString(",")
tempFilter.showType.value + ","
+ tempFilter.enquiries.map { it.value }.joinToString(",") + ","
+ tempFilter.ages.map { it.value }.joinToString(",") + ","
+ tempFilter.others.map { it.value }.joinToString(",") +","
+ tempFilter.doctorEdu.map { it.value }.joinToString(",")
)
BuryPointUtils.buryPoint("Filtrate", props1)
......@@ -1069,6 +1076,9 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
allFilter.enquiries.addAll(tempFilter.enquiries)
allFilter.ages.clear()
allFilter.ages.addAll(tempFilter.ages)
//学历
allFilter.doctorEdu.clear()
allFilter.doctorEdu.addAll(tempFilter.doctorEdu)
// 擅长人群
allFilter.specialityCrowd.clear()
allFilter.specialityCrowd.addAll(tempFilter.specialityCrowd)
......@@ -1176,7 +1186,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
//筛选标题显示处理
private fun filterLabelSet() {
if ((allFilter.others.size + allFilter.ages.size + allFilter.enquiries.size + allFilter.title.size+allFilter.specialityCrowd.size) == 1) {
if ((allFilter.others.size + allFilter.ages.size + allFilter.doctorEdu.size + allFilter.enquiries.size + allFilter.title.size + allFilter.specialityCrowd.size) == 1) {
var text: String? = ""
if (allFilter.others.size == 1) {
text = allFilter.others[0].value
......@@ -1186,8 +1196,11 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
text = allFilter.enquiries[0].value
} else if (allFilter.title.size == 1) {
text = allFilter.title[0].value
}else if (allFilter.specialityCrowd.size==1){
} else if (allFilter.specialityCrowd.size == 1) {
text = allFilter.specialityCrowd[0].value
}else if(allFilter.doctorEdu.size == 1){
//学历
text = allFilter.doctorEdu[0].value
} else {
text = "筛选"
}
......@@ -1488,6 +1501,7 @@ class ExpertSearchActivity : BaseMvpActivity<IExpertSearchView, ExpertSearchPres
allFilter.sub = SubItem()
allFilter.enquiries.clear()
allFilter.ages.clear()
allFilter.doctorEdu.clear()
allFilter.others.clear()
updateFilterTextViewStatus(tvSubject, FILTER_STATUS_NORMAL)
updateFilterTextViewStatus(tvArea, FILTER_STATUS_NORMAL)
......
......@@ -608,7 +608,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
}
}
}
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.title.size+allFilter.specialityCrowd.size > 0) {
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size+allFilter.doctorEdu.size + allFilter.title.size+allFilter.specialityCrowd.size > 0) {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_FILTERED)
} else {
updateFilterTextViewStatus(tvFilter, FILTER_STATUS_NORMAL)
......@@ -973,6 +973,9 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
tempFilter.showType = allFilter.showType
tempFilter.ages.clear()
tempFilter.ages.addAll(allFilter.ages)
//学历
tempFilter.doctorEdu.clear()
tempFilter.doctorEdu.addAll(allFilter.doctorEdu)
tempFilter.enquiries.clear()
tempFilter.enquiries.addAll(allFilter.enquiries)
// 擅长人群添加数据
......@@ -988,7 +991,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
filterPopupWindow.setOnDismissListener {
viewDim.visibility = View.INVISIBLE
viewDim_filter.visibility = View.GONE
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.title.size+allFilter.specialityCrowd.size > 0 || !TextUtils.isEmpty(
if (allFilter.others.size + allFilter.enquiries.size + allFilter.ages.size + allFilter.doctorEdu.size + allFilter.title.size+allFilter.specialityCrowd.size > 0 || !TextUtils.isEmpty(
allFilter.priceRanges?.minPrice
) || !TextUtils.isEmpty(allFilter.priceRanges?.maxPrice)
) {
......@@ -1024,10 +1027,11 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
)
props1.put(
"filtrate_second",
tempFilter.showType.value + "," + tempFilter.enquiries.map { it.value }
.joinToString(",") + "," + tempFilter.ages.map { it.value }.joinToString(
","
) + "," + tempFilter.others.map { it.value }.joinToString(",")
tempFilter.showType.value + ","
+ tempFilter.enquiries.map { it.value }.joinToString(",") + ","
+ tempFilter.ages.map { it.value }.joinToString(",") + ","
+ tempFilter.doctorEdu.map { it.value }.joinToString(",") + ","
+ tempFilter.others.map { it.value }.joinToString(",")
)
BuryPointUtils.buryPoint("Filtrate", props1)
......@@ -1037,6 +1041,8 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
allFilter.enquiries.addAll(tempFilter.enquiries)
allFilter.ages.clear()
allFilter.ages.addAll(tempFilter.ages)
allFilter.doctorEdu.clear()
allFilter.doctorEdu.addAll(tempFilter.doctorEdu)
// 擅长人群
allFilter.specialityCrowd.clear()
allFilter.specialityCrowd.addAll(tempFilter.specialityCrowd)
......@@ -1145,7 +1151,7 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
//筛选标题显示处理
private fun filterLabelSet() {
if ((allFilter.others.size + allFilter.ages.size + allFilter.enquiries.size + allFilter.title.size+allFilter.specialityCrowd.size) == 1) {
if ((allFilter.others.size + allFilter.ages.size + allFilter.doctorEdu.size + allFilter.enquiries.size + allFilter.title.size+allFilter.specialityCrowd.size) == 1) {
var text: String? = ""
when {
allFilter.others.size == 1 -> {
......@@ -1163,6 +1169,9 @@ class ExpertSearchFragment : BaseMvpFragment<IExpertSearchView, ExpertSearchPres
allFilter.specialityCrowd.size==1 -> {
text = allFilter.specialityCrowd[0].value
}
allFilter.doctorEdu.size==1 -> {
text = allFilter.doctorEdu[0].value
}
else -> {
text = "筛选"
}
......
......@@ -139,6 +139,10 @@ class ExpertSearchPresenter : SimplePresenter<IExpertSearchView>() {
if (allFilter.ages.isNotEmpty()) {
sb.append("&ages=").append(allFilter.ages.map { it.key }.joinToString(","))
}
if (allFilter.doctorEdu.isNotEmpty()) {
sb.append("&edus=").append(allFilter.doctorEdu.map { it.key }.joinToString(","))
}
// 擅长人群拼接
if (allFilter.specialityCrowd.isNotEmpty()) {
sb.append("&crowdsTags=")
......
......@@ -15,14 +15,9 @@ import com.ydl.webview.NewH5Activity
import com.ydl.ydl_image.config.SimpleImageOpConfiger
import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydlcommon.base.config.HttpConfig
import com.ydl.ydlcommon.data.PlatformDataManager
import com.ydl.ydlcommon.router.IYDLRouterConstant
import com.ydl.ydlcommon.utils.BuryPointUtils
import com.ydl.ydlcommon.utils.URLUtils
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils
import com.ydl.ydlcommon.utils.remind.ToastHelper
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxImageTool
import com.yidianling.consultant.ExpertSearchActivity
import com.yidianling.consultant.IExpertSearchView
import com.yidianling.consultant.R
......@@ -89,15 +84,19 @@ class ExpertSearchAdapter(
holder.imgHead_online.visibility = View.GONE
} else {
//不是服务中且问询人数大于0
if (itemBean.chatNum > 5) {
when {
itemBean.chatNum > 5 -> {
holder.chat_people_in_question.visibility = View.VISIBLE
holder.chat_people_in_question.text = "多人在问询"
} else if (itemBean.chatNum > 0) {
}
itemBean.chatNum > 0 -> {
holder.chat_people_in_question.visibility = View.VISIBLE
holder.chat_people_in_question.text = "${itemBean.chatNum}人在问询"
} else {
}
else -> {
holder.chat_people_in_question.visibility = View.GONE
}
}
//可预约
holder.imgHead_online_server.visibility = View.GONE
if (itemBean.isTodayFree == true) {
......@@ -158,19 +157,23 @@ class ExpertSearchAdapter(
} else {
holder.imgFightEpidemicIcon.visibility = View.GONE
//能力等级标签
if (1 == itemBean.abilityLevel) {
when (itemBean.abilityLevel) {
1 -> {
//实习
holder.imgAbilityLevel.background =
context.resources.getDrawable(R.drawable.consultant_expert_search_shixi)
holder.imgAbilityLevel.visibility = View.VISIBLE
} else if (2 == itemBean.abilityLevel) {
}
2 -> {
//新手
holder.imgAbilityLevel.background =
context.resources.getDrawable(R.drawable.consultant_expert_search_xinshou)
holder.imgAbilityLevel.visibility = View.VISIBLE
} else {
}
else -> {
holder.imgAbilityLevel.visibility = View.GONE
}
}
//活动图标
if (!TextUtils.isEmpty(itemBean.activityImg)) {
holder.imgActivity.visibility = View.VISIBLE
......@@ -223,15 +226,18 @@ class ExpertSearchAdapter(
holder.tvTeamCertifications.text = itemBean.teamCertifications
//咨询师标签
holder.ll_tags.removeAllViews()
if (!TextUtils.isEmpty(itemBean.tags)) {
val tagList = itemBean.tags!!.split("|")
for (tag in tagList) {
if (!TextUtils.isEmpty(tag)) {
val view = LayoutInflater.from(context)
.inflate(R.layout.consultant_item_tag, holder.ll_tags, false)
view.tvTag.text = tag
holder.ll_tags.addView(view)
if (itemBean.tagList.isNotEmpty()){
for (tag in itemBean.tagList){
val view = LayoutInflater.from(context).inflate(R.layout.consultant_item_tag, holder.ll_tags, false)
view.tvTag.text = tag.tagName
if (tag.isHigh==1){
view.tvTag.setBackgroundResource(R.drawable.consultant_bg_radius_line_eb892c)
view.tvTag.setTextColor(ContextCompat.getColor(context,R.color.color_EB892C))
}else{
view.tvTag.setBackgroundResource(R.drawable.consultant_bg_radius_line_gray_1)
view.tvTag.setTextColor(ContextCompat.getColor(context,R.color.platform_color_E0E0E0))
}
holder.ll_tags.addView(view)
}
}
//帮助人数
......
......@@ -12,6 +12,7 @@ class ConsultBIConstants {
const val POSITION_CONSULT_TYPE_CLICK = "consult_type_click" //咨询方式
const val POSITION_AVERAGE_SERVICE_INPUT = "average_service_input" //服务均价
const val POSITION_AGE_CHOICE_CLICK = "age_choice_click" //年龄选择
const val POSITION_EDU_CHOICE_CLICK = "education_background_click" //学历选择
const val POSITION_QUALIFICATION_CHOICE_CLICK = "qualification_choice_click" //资质选择
const val POSITION_GOOD_AT_CLICK = "good_at_click" // 擅长人群
const val POSITION_OTHER_CHOICE_CLICK = "other_choice_click" //其他选择
......
......@@ -19,6 +19,7 @@ data class AllFilter(
var priceRanges: PriceRangesItem ?= null, //服务均价
var priceRangesView: TextView ?= null, //服务均价
val ages: ArrayList<AgeItem> = ArrayList(), //年龄
val doctorEdu: ArrayList<DoctorEduItem> = ArrayList(), //学历
val others: ArrayList<OtherItem> = ArrayList(),//其他筛选
val title:ArrayList<ReorderItem> = ArrayList(), //资质
......
package com.yidianling.consultant.model.bean
import com.google.gson.annotations.SerializedName
/**
* 搜索条件 学历返回数据
* */
data class DoctorEduItem(
@field:SerializedName("key")
var key: Int? = null,
@field:SerializedName("value")
var value: String? = null
)
\ No newline at end of file
......@@ -130,5 +130,15 @@ data class DoctorServiceItem(
/**
* 私聊按钮的文案(如果不为空则取这个字段的值,如果为空 则默认为:“私聊”)
*/
val chatBtnText: String?
val chatBtnText: String?,
/**
* 新标签分类
*/
val tagList: ArrayList<TagBean>
)
data class TagBean(
val tagName:String?,
val isHigh:Int
)
\ No newline at end of file
......@@ -4,6 +4,12 @@ import com.google.gson.annotations.SerializedName
data class Filters(
/**
* 学历
*/
@field:SerializedName("doctor_edu")
val doctorEdu: List<DoctorEduItem> = ArrayList(),
/**
* 按服务或者按专家
*/
@field:SerializedName("show_type")
......
......@@ -90,14 +90,22 @@ class FilterPopupWindow(
// this.animationStyle = R.style.consultant_expert_service_popupwindow_filter_anim_style
initShowTypeViews(view)
//咨询方式
initEnquiryViews(view)
//服务均价
initPriceViews(view)
//年龄选择
initAgeViews(view)
//其他选择
initOtherViews(view)
//擅长人群
initGoodAtCrowd(view)
//资质
initZiZhiViews(view)
initKeyboardListener(view)
//学历选择
initEduViews(view)
initKeyboardListener(view)
updateCount()
view.btnReset.setOnClickListener {
......@@ -137,6 +145,7 @@ class FilterPopupWindow(
private fun reset() {
tempFilter.showType = filterData.showType[0]
tempFilter.ages.clear()
tempFilter.doctorEdu.clear()
tempFilter.enquiries.clear()
// 擅长人群
tempFilter.specialityCrowd.clear()
......@@ -230,6 +239,13 @@ class FilterPopupWindow(
biEventParams = tempFilter.ages.map { it.key }.joinToString(",")
}
}
//学历
if (tempFilter.doctorEdu.isNotEmpty()) {
sb.append("&edus=").append(tempFilter.doctorEdu.map { it.key }.joinToString(","))
if (ConsultBIConstants.POSITION_EDU_CHOICE_CLICK == biEventName) {
biEventParams = tempFilter.doctorEdu.map { it.value }.joinToString(",")
}
}
// 擅长人群拼接
if (tempFilter.specialityCrowd.isNotEmpty()){
sb.append("&crowdsTags=").append(tempFilter.specialityCrowd.map { it.key }.joinToString(","))
......@@ -324,7 +340,9 @@ class FilterPopupWindow(
fun addSubscription(disposable: Disposable) {
mDisposableList.add(disposable)
}
/**
* 其他选择
* */
private fun initOtherViews(view: View) {
val mWidth = (popWidth - RxImageTool.dp2px(52f)) / enquirySize
for ((index, other) in filterData.other.withIndex()) {
......@@ -363,6 +381,9 @@ class FilterPopupWindow(
}
}
/**
* 资质
* */
private fun initZiZhiViews(view: View) {
val mWidth = (popWidth - RxImageTool.dp2px(40f)) / 2
for (other in filterData.title) {
......@@ -455,7 +476,9 @@ class FilterPopupWindow(
}
}
/**
* 年龄
* */
private fun initAgeViews(view: View) {
val mWidth = (popWidth - RxImageTool.dp2px(52f)) / enquirySize
for ((index, age) in filterData.age.withIndex()) {
......@@ -493,6 +516,46 @@ class FilterPopupWindow(
view.flAge.addView(textView)
}
}
/**
* 学历
* */
private fun initEduViews(view: View) {
val mWidth = (popWidth - RxImageTool.dp2px(52f)) / enquirySize
for ((index, edu) in filterData.doctorEdu.withIndex()) {
val textView = View.inflate(context, R.layout.consultant_item_filter, null) as TextView
val params = FrameLayout.LayoutParams(mWidth, RxImageTool.dp2px(36f))
val marginNum = RxImageTool.dp2px(5f)
params.setMargins(
marginNum + (dp10 + mWidth) * (index % enquirySize),
dp46 * (index / enquirySize),
marginNum,
0
)
textView.layoutParams = params
textView.text = edu.value
ageViews.add(textView)
if (tempFilter.doctorEdu.contains(edu)) {
textView.isSelected = true
textView.paint.isFakeBoldText = true
}
textView.text = " " + edu.value + " "
textView.setOnClickListener {
if (textView.isSelected) {
tempFilter.doctorEdu.remove(edu)
textView.isSelected = false
textView.paint.isFakeBoldText = false
} else {
tempFilter.doctorEdu.add(edu)
textView.isSelected = true
textView.paint.isFakeBoldText = true
}
updateCount(ConsultBIConstants.POSITION_EDU_CHOICE_CLICK)
}
view.fl_edu.addView(textView)
}
}
private fun initEnquiryViews(view: View) {
val mWidth = (popWidth - RxImageTool.dp2px(52f)) / enquirySize
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp"/>
<solid android:color="@color/color_1AEB892C" />
<stroke android:width="0.5dp" android:color="@color/color_EB892C"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp"></corners>
<corners android:radius="1dp"/>
<solid android:color="@color/platform_white" />
<stroke android:width="0.5dp" android:color="@color/platform_color_E0E0E0"/>
......
......@@ -3,12 +3,11 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tvTag"
android:layout_width="wrap_content"
android:layout_height="14dp"
android:layout_height="wrap_content"
android:background="@drawable/consultant_bg_radius_line_gray_1"
android:gravity="center"
android:paddingLeft="4dp"
android:layout_marginRight="6dp"
android:layout_marginEnd="6dp"
android:padding="3dp"
android:textColor="@color/platform_color_999999"
android:paddingRight="4dp"
android:textSize="10dp"
android:textSize="10sp"
tools:text="恋爱情感" />
......@@ -119,6 +119,21 @@
android:paddingLeft="5dp"
app:lineSpacing="10dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/platform_dp_28"
android:text="学历选择"
android:textColor="@color/platform_color_242424"
android:textSize="@dimen/platform_dp_16"
android:textStyle="bold" />
<FrameLayout
android:id="@+id/fl_edu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp" />
<LinearLayout
android:id="@+id/ll_crowd_more"
android:layout_width="match_parent"
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
<!-- google color-->
<color name="consultant_color_FF9500">#FF9500</color>
......@@ -24,5 +24,7 @@
<color name="consultant_colorBg">#f5f5f5</color>
<color name="color_EB892C">#EB892C</color>
<color name="color_1AEB892C">#1AEB892C</color>
</resources>
......@@ -135,7 +135,8 @@ public class DynamicApiUtils {
return YDLHttpUtils.Companion.obtainApi(NetApiStore.class).reportWorry(getMaps(list));
}
//发布动态
//发布
// 动态
public static Observable<BaseResponse<PublishTrendResult>> publishTrend(Command.PublishTrend cmd, File... files) {
Map<String, RequestBody> map = NetworkParamsUtils.getFileMaps(cmd, "FILE", files);
return YDLHttpUtils.Companion.obtainApi(NetApiStore.class).publishTrend(map);
......
package com.yidianling.im.bean;
import com.ydl.ydlcommon.data.http.BaseCommand;
public class TeamAlreadyReadBean extends BaseCommand {
public String tid;
public String uid;
public TeamAlreadyReadBean(String tid, String uid) {
this.tid = tid;
this.uid = uid;
}
}
package com.yidianling.im.event
class ChatGroupStatusEvent()
\ No newline at end of file
......@@ -70,6 +70,7 @@ interface ImApi {
@POST("consult/get-expert")
fun getExpert(@FieldMap params: Map<String, String>): Observable<BaseResponse<IMExpertBuild>>
//以下接口为消息改版后新加
//私聊 获取各消息未读数
@GET("chat/getNotifyCountMessage")
......
......@@ -50,4 +50,5 @@ interface ImHttp {
fun getInteractMessage(param: InteractMessageParam): Observable<BaseAPIResponse<InteractBean>>
fun getUnreadMessage(param: UnreadParam): Observable<BaseAPIResponse<UnreadMessageBean>>
}
\ No newline at end of file
......@@ -37,6 +37,11 @@ interface ImRetrofitApi {
@POST("consult/get-expert")
fun getExpert(@FieldMap params: Map<String, String>): Observable<BaseResponse<IMExpertBuild>>
//群聊 群聊Ait艾特符号已读
@POST("message/chatRoom/readApnsMessage")
@Headers(YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun teamChatALreadyRead(@Body params: Map<String, String>): Observable<BaseResponse<Any>>
//获取用户的状态(用户、专家、助理)
@GET("user/userType")
......
......@@ -408,7 +408,9 @@ public class SessionHelper {
ArrayList<BaseAction> actions = new ArrayList<>();
actions.add(new ImageAction());
actions.add(new VideoAction());
actions.add(avChatAction);
//去掉群聊的视频通话按钮
// actions.add(avChatAction);
SessionTeamCustomization.SessionTeamCustomListener listener = new SessionTeamCustomization.SessionTeamCustomListener() {
@Override
......
......@@ -18,7 +18,6 @@ import com.ydl.ydlcommon.bean.StatusBarOptions
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils.Companion.count
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.ToastUtil
import com.yidianling.im.R
import com.yidianling.im.api.event.ImLogoutEvent
......@@ -41,6 +40,7 @@ import com.yidianling.im.ui.page.fragment.bean.UnreadMessageBean
import com.yidianling.im.ui.page.popupWindow.ChatSettingPopupWindow
import com.yidianling.im.ui.param.ClearMessageParam
import com.yidianling.im.ui.param.UnreadParam
import com.yidianling.uikit.api.NimUIKit
import de.greenrobot.event.EventBus
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
......@@ -354,6 +354,7 @@ class NewMultiMessageFragment : BaseFragment() {
} else {
ToastUtil.toastShort("请登录后再试")
}
NimUIKit.startYDLChatting(context,"4597318766",SessionTypeEnum.Team,null,null,null)
}
}
/**
......
......@@ -7,12 +7,17 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.jcodecraeer.xrecyclerview.CustomFooterViewCallBack
import com.jcodecraeer.xrecyclerview.XRecyclerView
import com.ydl.ydlcommon.base.BaseFragment
import com.ydl.ydlcommon.data.http.BaseResponse
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.utils.NetworkParamsUtils
import com.ydl.ydlcommon.utils.NetworkParamsUtils.getMaps
import com.yidianling.common.tools.ToastUtil
import com.yidianling.im.R
import com.yidianling.im.bean.TeamAlreadyReadBean
import com.yidianling.im.event.MessageListRefreshEvent
import com.yidianling.im.helper.MsgReceiveHelper
import com.yidianling.im.http.ImHttpImpl
import com.yidianling.im.http.ImRetrofitApi
import com.yidianling.im.router.ImIn
import com.yidianling.im.ui.page.fragment.adapter.ChatAdapter
import com.yidianling.im.ui.page.fragment.bean.ChatItemBean
......@@ -21,6 +26,8 @@ import com.yidianling.im.ui.page.fragment.view.ChatFooterItemView
import com.yidianling.im.ui.page.widget.ChatUnusualView
import com.yidianling.im.ui.param.ChatParam
import de.greenrobot.event.EventBus
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.im_chat_fragment_layout.*
/**
......@@ -87,7 +94,7 @@ class ChatFragment : BaseFragment(), XRecyclerView.LoadingListener {
if (ImIn.getUserInfo()?.uid != "0") {
var dis = ImHttpImpl.getInstance()
.getAllChatMessage(ChatParam("${ImIn.getUserInfo()?.uid}", "${selectType}"))
.getAllChatMessage(ChatParam("${ImIn.getUserInfo()?.uid}", "${selectType}","1"))
.compose(RxUtils.applySchedulers(this))
.compose<ChatModelBean>(RxUtils.resultJavaData())
.subscribe({ it ->
......@@ -224,6 +231,12 @@ class ChatFragment : BaseFragment(), XRecyclerView.LoadingListener {
getChatMessageData()
}
})
chatAdapter?.setChatAitReadlistener(object :ChatAdapter.ChatAitAlreadyRead{
override fun alreadyReadAit(tid:String) {
//群聊已读消息
TeamAlreadyRead(tid)
}
})
chat_recyclerview.layoutManager = LinearLayoutManager(context)
chat_recyclerview.adapter = chatAdapter
chat_recyclerview.setLoadingListener(this)
......@@ -241,6 +254,20 @@ class ChatFragment : BaseFragment(), XRecyclerView.LoadingListener {
})
}
private fun TeamAlreadyRead(tid: String) {
val cmd = TeamAlreadyReadBean(tid, ImIn.getUserInfo()?.uid.toString())
val disposable =
ImRetrofitApi.getImJavaApi().teamChatALreadyRead(getMaps(cmd))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp: BaseResponse<Any> ->
}
) { throwable: Throwable ->
}
}
override fun onResume() {
super.onResume()
resetPageShow()
......
......@@ -15,6 +15,7 @@ import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.utils.log.LogHelper
import com.ydl.ydlcommon.utils.remind.ToastHelper
import com.ydl.ydlcommon.view.ListNoCancelDialog
import com.yidianling.common.tools.ToastUtil
import com.yidianling.im.api.param.RmHistoryParam
import com.yidianling.im.api.param.RmTalkParam
import com.yidianling.im.api.param.TopMessageParam
......@@ -23,11 +24,15 @@ import com.yidianling.im.event.UpdateTabUnreadNumEvent
import com.yidianling.im.helper.IMChatUtil
import com.yidianling.im.helper.MsgReceiveHelper
import com.yidianling.im.http.ImHttpImpl
import com.yidianling.im.router.ImIn
import com.yidianling.im.session.SessionHelper
import com.yidianling.im.ui.page.fragment.bean.ChatItemBean
import com.yidianling.im.ui.page.fragment.bean.ChatModelBean
import com.yidianling.im.ui.page.fragment.view.ChatItemView
import com.yidianling.im.ui.page.fragment.view.ChatTimeItemView
import com.yidianling.im.ui.param.ChatParam
import de.greenrobot.event.EventBus
import kotlinx.android.synthetic.main.im_chat_fragment_layout.*
/**
* 互动列表适配器
......@@ -63,9 +68,15 @@ class ChatAdapter(var context: Context, private var mList: ArrayList<ChatItemBea
P2PCustomActionHandlerImpl("4108805", "课程小助手-壹壹", "4108805"))
}else {
// IMUtil.startChat(context as AppCompatActivity, mList[position].toUid.toString(), 0, 0, null, 0, true)
if (mList[position].chat_type==2){//群聊
mChatListener?.alreadyReadAit(mList[position].toUid.toString())
SessionHelper.startTeamSession(context,mList[position].toUid.toString())
}else{//单聊
IMChatUtil.startChat(context as AppCompatActivity, mList[position])
}
}
}
holder.view.setOnLongClickListener {
......@@ -214,6 +225,16 @@ class ChatAdapter(var context: Context, private var mList: ArrayList<ChatItemBea
fun onRefresh() //刷新聊天列表
}
private var mChatListener: ChatAitAlreadyRead? = null
fun setChatAitReadlistener(mChatListener: ChatAitAlreadyRead) {
this.mChatListener = mChatListener
}
interface ChatAitAlreadyRead {
fun alreadyReadAit( tid:String) //群聊艾特符号
}
/**
* 互动列表正常item的holder
*/
......
......@@ -20,7 +20,7 @@ class ChatItemBean(
var timestamp: Long = 0.toLong(),
var title: String = "",
var toName: String = "",
var toUid: Int = 0,
var toUid: Long = 0,
var type: Int = 0,//私聊群聊type=3
var utype: Int = 0,
var timeStr: String = "",
......@@ -28,5 +28,6 @@ class ChatItemBean(
var doctorTitle: String = "",
var isThreeItem: Boolean = false, //是否是三周前时间展示item
var listenOrderStatus: Int = 0, // 倾诉状态
var orderStatus: Int = 0 //咨询状态
var orderStatus: Int = 0 ,//咨询状态
var noReadAtContent:String?=""
)
\ No newline at end of file
......@@ -5,10 +5,10 @@ import android.text.Html
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.RelativeLayout
import com.netease.nimlib.sdk.NIMClient
import com.netease.nimlib.sdk.team.TeamService
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.im.R
import com.yidianling.im.helper.MsgReceiveHelper
import com.yidianling.im.preference.ImTempData
import com.yidianling.im.ui.page.fragment.bean.ChatItemBean
import kotlinx.android.synthetic.main.im_chat_item_view.view.*
......@@ -73,10 +73,27 @@ class ChatItemView(mContext: Context) : LinearLayout(mContext) {
bean.toUid.toString()
)
chat_message_content.setText(Html.fromHtml(th))
}else if (!bean.noReadAtContent.isNullOrEmpty()){
var th = "<font color='#FF7766' charset='utf-8'>[有人@我]</font> " + bean.content;
chat_message_content.setText(Html.fromHtml(th));
}else {
chat_message_content.text = bean.content
}
if (bean.is_top == 1) {
chat_global_ll.setBackgroundResource(R.drawable.im_chat_is_top_bg)
} else {
chat_global_ll.setBackgroundResource(0)
}
//如果是群聊 根据免打扰状态判断逻辑
if (bean.chat_type==2){
val notifyType = NIMClient.getService(TeamService::class.java)
.queryTeamBlock(bean.toUid.toString()).messageNotifyType.value // 群消息提醒
if (notifyType==0){
//有消息提醒
not_disturb.visibility=View.GONE
if (bean.unReadNum > 99) {
chat_message_unread_num.visibility = View.VISIBLE
chat_message_unread_num.text = "99+"
......@@ -86,11 +103,30 @@ class ChatItemView(mContext: Context) : LinearLayout(mContext) {
} else {
chat_message_unread_num.visibility = View.GONE
}
if (bean.is_top == 1) {
chat_global_ll.setBackgroundResource(R.drawable.im_chat_is_top_bg)
}else{
val layoutParams: ViewGroup.LayoutParams = chat_message_unread_num.getLayoutParams()
layoutParams.height = 36
layoutParams.width = 36
chat_message_unread_num.setLayoutParams(layoutParams)
not_disturb.visibility=View.VISIBLE
if (bean.unReadNum > 0){
chat_message_unread_num.visibility=View.VISIBLE
chat_message_unread_num.text=""
}else{
chat_message_unread_num.visibility = View.GONE
}
}
}else{
if (bean.unReadNum > 99) {
chat_message_unread_num.visibility = View.VISIBLE
chat_message_unread_num.text = "99+"
} else if (bean.unReadNum > 0) {
chat_message_unread_num.visibility = View.VISIBLE
chat_message_unread_num.text = "${bean.unReadNum}"
} else {
chat_global_ll.setBackgroundResource(0)
chat_message_unread_num.visibility = View.GONE
}
not_disturb.visibility=View.GONE
}
}
......
......@@ -4,4 +4,4 @@ package com.yidianling.im.ui.param
* 消息列表请求参数 selectTab:0(全部),1(服务中),2(服务过)
* Created by xj on 2019/10/21.
*/
data class ChatParam(var uid: String, var selectType: String)
\ No newline at end of file
data class ChatParam(var uid: String, var selectType: String,var includeGroupChat:String="1")
\ No newline at end of file
......@@ -176,7 +176,8 @@ public class AitManager implements TextWatcher {
if (s.toString().equals("@")) {
// 启动@联系人界面
if (!TextUtils.isEmpty(tid) ) {
AitContactSelectorActivity.start(context, tid);
//暂时注释艾特相关群成员功能
// AitContactSelectorActivity.start(context, tid);
}
}
aitContactsModel.onInsertText(start, s.toString());
......
......@@ -167,9 +167,11 @@ public class YDLP2PMessageActivity extends YDLBaseMessageActivity {
//读取未发送的临时消息
if (ActionHandlerStorage.getL(sessionId) != null) {
if (messageFragment.getInputPanel().getInputContent() == null || messageFragment.getInputPanel().getInputContent().equals("")) {
if (messageFragment.getInputPanel()==null||messageFragment.getInputPanel().getInputContent() == null || messageFragment.getInputPanel().getInputContent().equals("")) {
if (messageFragment.getInputPanel()!=null){
messageFragment.getInputPanel().setInputContent(ActionHandlerStorage.getL(sessionId).getImTempData(sessionId));
}
}
if (ActionHandlerStorage.needLoadNewMsg) {
((BaseFetchLoadAdapter.RequestFetchMoreListener) messageFragment.getMessageListPanelEx().getMessageLoder(null)).onFetchMoreRequested();
ActionHandlerStorage.needLoadNewMsg = false;
......
......@@ -216,7 +216,9 @@ public class YDLTeamMessageActivity extends YDLBaseMessageActivity {
team = d;
fragment.setTeam(team);
setTitle(team == null ? sessionId : team.getName() + "(" + team.getMemberCount() + "人)");
//暂时去掉群聊人数标题
// setTitle(team == null ? sessionId : team.getName() + "(" + team.getMemberCount() + "人)");
setTitle(team == null ? sessionId : team.getName() );
invalidTeamTipText.setText(team.getType() == TeamTypeEnum.Normal ? R.string.im_normal_team_invalid_tip : R.string.im_team_invalid_tip);
invalidTeamTipView.setVisibility(team.isMyTeam() ? View.GONE : View.VISIBLE);
......@@ -300,7 +302,7 @@ public class YDLTeamMessageActivity extends YDLBaseMessageActivity {
};
@Override
protected YDLMessageFragment fragment() {
protected YDLTeamMessageFragment fragment() {
// 添加fragment
Bundle arguments = getIntent().getExtras();
arguments.putSerializable(Extras.EXTRA_TYPE, SessionTypeEnum.Team);
......
......@@ -4,9 +4,13 @@ import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
......@@ -22,12 +26,10 @@ import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
......@@ -36,7 +38,6 @@ import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.constant.MsgStatusEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.CustomMessageConfig;
......@@ -47,20 +48,28 @@ import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import com.ydl.webview.H5Params;
import com.ydl.webview.NewH5Activity;
import com.ydl.ydl_image.module.GlideApp;
import com.ydl.ydlcommon.base.config.HttpConfig;
import com.ydl.ydlcommon.data.PlatformDataManager;
import com.ydl.ydlcommon.data.http.RxUtils;
import com.ydl.ydlcommon.modular.ModularServiceManager;
import com.ydl.ydlcommon.ui.LoadingDialogFragment;
import com.ydl.ydlcommon.utils.AnimUtils;
import com.ydl.ydlcommon.utils.LogUtil;
import com.ydl.ydlcommon.utils.NetworkParamsUtils;
import com.ydl.ydlcommon.utils.SharedPreferencesEditor;
import com.ydl.ydlcommon.utils.YdlBuryPointUtil;
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils;
import com.ydl.ydlcommon.utils.log.AliYunLogConfig;
import com.ydl.ydlcommon.utils.log.AliYunRichLogsHelper;
import com.ydl.ydlcommon.utils.log.LogHelper;
import com.ydl.ydlcommon.utils.remind.HttpErrorUtils;
import com.ydl.ydlcommon.view.CircleImageView;
import com.ydl.ydlcommon.view.dialog.CommonDialog;
import com.ydl.ydlcommon.view.dialog.ListDialog;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.im.R;
import com.yidianling.im.bean.RemoveHistory;
import com.yidianling.im.config.constants.ImConstants;
import com.yidianling.im.event.MultipleAnswerBean;
import com.yidianling.im.event.MultipleSelectedEvent;
import com.yidianling.im.helper.IMChatUtil;
......@@ -86,6 +95,7 @@ import com.yidianling.uikit.api.NimUIKitImpl;
import com.yidianling.uikit.business.ait.AitManager;
import com.yidianling.uikit.business.session.activity.YDLBaseMessageActivity;
import com.yidianling.uikit.business.session.helper.ChatStatusCacheHelper;
import com.yidianling.uikit.business.session.helper.MessageListPanelHelper;
import com.yidianling.uikit.business.session.module.input.InputPanel;
import com.yidianling.uikit.business.session.module.list.MessageListPanelEx;
import com.yidianling.uikit.business.session.view.ChatPrivateTips;
......@@ -152,7 +162,7 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
private int rvPaddingTop;
private RelativeLayout rl_contain;
private boolean initHeightFinish;
public TitleBarBottom titleBar;
public InputPanel getInputPanel() {
return inputPanel;
}
......@@ -197,8 +207,7 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
private RelativeLayout constraint_ll;
private LinearLayout ll_info_detail;
private RelativeLayout rela_zixun;
protected RelativeLayout rela_zixun;
private ValueAnimator anim_out;
private ObjectAnimator sourceLayoutAnim;
private ValueAnimator anim_in;
......@@ -245,9 +254,13 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
parseIntent();
TitleBarBottom titleBar = ((YDLBaseMessageActivity) getActivity()).getTitleBarBottom();
titleBar = ((YDLBaseMessageActivity) getActivity()).getTitleBarBottom();
titleBar.setTitleLeftDraw(getResources().getDrawable(R.drawable.loading_01));
titleBar.setTitle("正在连接中...");
if (sessionType==SessionTypeEnum.Team){
titleBar.setRightIcon(getContext().getDrawable(R.drawable.platform_common_more));
}
fl_container = rootView.findViewById(R.id.message_activity_list_view_container);
v_chattips = rootView.findViewById(R.id.v_chattips);
lin_actions = rootView.findViewById(R.id.lin_actions);
......@@ -280,13 +293,13 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
question_multiple = rootView.findViewById(R.id.question_multiple);
//做灵犀2.0 去掉常用语逻辑
//rl_common_question_enter.setVisibility(ActionHandlerStorage.getL(sessionId) != null && ActionHandlerStorage.getL(sessionId).getUserType() == 3 ? View.VISIBLE : View.GONE);
if (ActionHandlerStorage.getL(sessionId).getUserType() != 2) {
if (null!=ActionHandlerStorage.getL(sessionId)&&ActionHandlerStorage.getL(sessionId).getUserType() != 2) {
if (null != getActivity() && null != rela_zixun) {
rela_zixun.setVisibility(View.GONE);
}
}
if (ActionHandlerStorage.getL(sessionId).isNotPrepare()) {
if (null!=ActionHandlerStorage.getL(sessionId)&&ActionHandlerStorage.getL(sessionId).isNotPrepare()) {
IMChatUtil.INSTANCE.prepareChatData((AppCompatActivity) getActivity(), sessionId, (expertInfo) -> {
String toUid = expertInfo.shareData.toUid;
IP2PCustomActionHandler handler = ActionHandlerStorage.getL(sessionId);
......@@ -303,6 +316,12 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
} else {
initView();
}
//如果是群聊
if (SessionTypeEnum.Team==sessionType){
rela_zixun.setVisibility(View.GONE);
titleBar.setTitleRightDraw(null);
}
}
@SuppressLint("CheckResult")
......@@ -348,7 +367,9 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
} else {
titleBar.setTitleRightDraw(getResources().getDrawable(R.drawable.im_erduoxiaolv));
}
if (ActionHandlerStorage.getL(sessionId)!=null){
titleBar.setTitle(ActionHandlerStorage.getL(sessionId).getInfo().name);
}
// 初始化顶部专家信息栏
if (ActionHandlerStorage.getL(sessionId) != null && ActionHandlerStorage.getL(sessionId).getUserType() == 2) {
top_expert_info_cl.setVisibility(View.VISIBLE);
......@@ -398,7 +419,7 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
//初始化私聊页面配置
initDefaultConfig();
if (ActionHandlerStorage.getL(sessionId).getInfo().doctorId != null){
if (null!=ActionHandlerStorage.getL(sessionId)&&ActionHandlerStorage.getL(sessionId).getInfo().doctorId != null){
// 获取专家是否在繁忙状态
ServiceImpl.Companion.getInstance().queryDoctorIsBusy(ActionHandlerStorage.getL(sessionId).getInfo().doctorId)
.subscribeOn(Schedulers.io())
......@@ -410,7 +431,17 @@ public class YDLMessageFragment extends TFragment implements ModuleProxy {
}
}
/**
* 是否隐藏输入框相关控件
*/
public void setGoneInput(boolean isGone){
if (isGone){
inputPanel.messageInputBar.setVisibility(View.GONE);
inputPanel.hideInputMethod();
}else {
inputPanel.messageInputBar.setVisibility(View.VISIBLE);
}
}
@SuppressLint("CheckResult")
private void initDefaultConfig() {
ServiceImpl.Companion.getInstance().getChatViewConfig()
......
package com.yidianling.uikit.business.session.fragment;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.team.TeamService;
import com.netease.nimlib.sdk.team.constant.TeamMemberType;
import com.netease.nimlib.sdk.team.constant.TeamMessageNotifyTypeEnum;
import com.netease.nimlib.sdk.team.model.Team;
import com.netease.nimlib.sdk.team.model.TeamMember;
import com.ydl.ydlcommon.data.http.RxUtils;
import com.ydl.ydlcommon.ui.LoadingDialogFragment;
import com.ydl.ydlcommon.utils.NetworkParamsUtils;
import com.ydl.ydlcommon.utils.log.LogHelper;
import com.ydl.ydlcommon.utils.remind.HttpErrorUtils;
import com.ydl.ydlcommon.view.dialog.CommonDialog;
import com.ydl.ydlcommon.view.dialog.ListDialog;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.im.R;
import com.yidianling.im.bean.RemoveHistory;
import com.yidianling.im.event.ChatGroupStatusEvent;
import com.yidianling.im.http.ImRetrofitApi;
import com.yidianling.im.router.ImIn;
import com.yidianling.nimbase.impl.cache.TeamDataCache;
import com.yidianling.uikit.api.NimUIKit;
import com.yidianling.uikit.business.session.helper.MessageListPanelHelper;
import com.yidianling.uikit.custom.widget.TitleBarBottom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.greenrobot.event.EventBus;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/**
* Created by zhoujianghua on 2015/9/10.
*/
......@@ -21,6 +54,7 @@ public class YDLTeamMessageFragment extends YDLMessageFragment {
private Team team;
@Override
public boolean isAllowSendMessage(IMMessage message) {
TeamMember teamMember= TeamDataCache.getInstance().getTeamMember(team.getId(), NimUIKit.getAccount());
......@@ -35,6 +69,12 @@ public class YDLTeamMessageFragment extends YDLMessageFragment {
}
@Override
public void onResume() {
super.onResume();
getChatGroupMute();
}
@Override
public boolean sendMessage(IMMessage message) {
if (!isAllowSendMessage(message)) {
return false;
......@@ -49,9 +89,129 @@ public class YDLTeamMessageFragment extends YDLMessageFragment {
return super.sendMessage(message);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
titleBar.setOnRightTextClick(new TitleBarBottom.OnTitleBarTextClick() {
@Override
public void onClick(View view, boolean isActive) {
List<String> list = new ArrayList<>();
int notifyType = NIMClient.getService(TeamService.class).queryTeamBlock(sessionId).getMessageNotifyType().getValue(); // 群消息提醒
// if (ImConstants.KEFUXIAOYI.equals(toChatUsername) || "4108805".equals(toChatUsername)) {
// list.add("历史聊天记录");
// list.add("客服热线");
// } else {
// if (notifyType==0){
// list.add("关闭群消息提醒");
// }else{
// list.add("开启群消息提醒");
// }
list.add("投诉反馈");
//
// list.add("历史聊天记录");
// list.add("删除聊天记录");
// }
list.add("删除聊天记录");
ListDialog.Builder dialog = new ListDialog.Builder(getContext(), list, 0, team.getName());
list.add("取消");
dialog.create().show();
dialog.SetOnItemClickLister(new ListDialog.Builder.OnItemClickLister() {
@Override
public void onItemClick(Dialog dialog, View view, int position) {
LogHelper.Companion.getInstance().writeLogSync(String.format("聊天界面:%s", list.get(position)));
switch (list.get(position)) {
case "开启群消息提醒":
case "关闭群消息提醒":
OpenCloseTeamMute(notifyType);
break;
case "投诉反馈":
ImIn.INSTANCE.feedBackIntent((Activity) getContext());
break;
case "返回首页":
ImIn.INSTANCE.mainIntent(getContext(), 0);
break;
case "客服热线":
// showCallDialog();
break;
case "历史聊天记录":
// historyMsg();
break;
case "删除聊天记录":
deleteChatHistory();
break;
case "ta的主页":
// showUserHome();
break;
case "取消":
break;
}
dialog.dismiss();
}
@Override
public void onItemLongClick(Dialog dialog, View view, int position) {
}
});
}
});
}
private void OpenCloseTeamMute(int notifyType) {
TeamMessageNotifyTypeEnum type = TeamMessageNotifyTypeEnum.All;
if (notifyType ==0){
type = TeamMessageNotifyTypeEnum.Mute;
}
NIMClient.getService(TeamService.class).muteTeam(team.getId(), type).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
ToastUtil.toastShort("成功");
// 设置成功
}
@Override
public void onFailed(int code) {
ToastUtil.toastShort(code+"");
// 设置失败
}
@Override
public void onException(Throwable exception) {
// 错误
}
});
}
public void onEventMainThread(ChatGroupStatusEvent event){
getChatGroupMute();
}
//获取群聊是否全员禁言
private void getChatGroupMute(){
boolean mute = NIMClient.getService(TeamService.class).queryTeamBlock(sessionId).isAllMute();
setGoneInput(mute);
}
public void setTeam(Team team) {
Log.e("hzs","-------------setTeam------------TeammessageFragment");
this.team = team;
}
/**
* 删除聊天记录
*/
private void deleteChatHistory() {
CommonDialog dialog = CommonDialog.create(getContext());
dialog.setMessage("确定删除与ta的聊天记录?");
dialog.setCancelAble(true);
dialog.setLeftOnclick("再考虑下", v -> dialog.dismiss());
dialog.setRightClick("立即删除", v -> {
ToastUtil.toastShort("聊天记录已删除");
NIMClient.getService(MsgService.class).clearServerHistory(team.getId(),SessionTypeEnum.Team);
MessageListPanelHelper.getInstance().notifyClearMessages(team.getId());
});
dialog.show();
}
}
\ No newline at end of file
......@@ -14,12 +14,15 @@ import com.netease.nimlib.sdk.team.model.MuteMemberAttachment;
import com.netease.nimlib.sdk.team.model.Team;
import com.netease.nimlib.sdk.team.model.UpdateTeamAttachment;
import com.yidianling.im.R;
import com.yidianling.im.event.ChatGroupStatusEvent;
import com.yidianling.uikit.api.NimUIKit;
import com.yidianling.uikit.business.team.helper.TeamHelper;
import java.util.List;
import java.util.Map;
import de.greenrobot.event.EventBus;
/**
* 系统消息描述文本构造器。主要是将各个系统消息转换为显示的文本内容。<br>
* Created by huangjun on 2015/3/11.
......@@ -165,7 +168,7 @@ public class TeamNotificationHelper {
StringBuilder sb = new StringBuilder();
for (Map.Entry<TeamFieldEnum, Object> field : a.getUpdatedFields().entrySet()) {
if (field.getKey() == TeamFieldEnum.Name) {
sb.append("名称被更新为 " + field.getValue());
sb.append("群名称修改为" +"\""+ field.getValue()+"\"");
} else if (field.getKey() == TeamFieldEnum.Introduce) {
sb.append("群介绍被更新为 " + field.getValue());
} else if (field.getKey() == TeamFieldEnum.Announcement) {
......@@ -197,10 +200,12 @@ public class TeamNotificationHelper {
} else if (field.getKey() == TeamFieldEnum.AllMute) {
TeamAllMuteModeEnum teamAllMuteModeEnum = (TeamAllMuteModeEnum) field.getValue();
if (teamAllMuteModeEnum == TeamAllMuteModeEnum.Cancel) {
sb.append("取消群全员禁言");
sb.append("群聊已开启");
} else {
sb.append("群全员禁言");
sb.append("群聊已结束,如有问题请联系个案管理师");
}
//发送通知告知群聊界面全员禁言或者取消全员禁言
EventBus.getDefault().post(new ChatGroupStatusEvent());
} else {
sb.append("群" + field.getKey() + "被更新为 " + field.getValue());
}
......
......@@ -57,7 +57,6 @@ import com.yidianling.nimbase.common.util.string.StringUtil;
import com.yidianling.uikit.api.NimUIKit;
import com.yidianling.uikit.api.NimUIKitImpl;
import com.yidianling.uikit.business.ait.AitTextChangeListener;
import com.yidianling.uikit.custom.bridge.ActionHandlerStorage;
import com.yidianling.uikit.custom.widget.SafeHelpRemindDialog;
import java.io.File;
......@@ -104,7 +103,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
protected View sendMessageButtonInInputBar;
/***发送消息按钮*/
protected View emojiButtonInInputBar;
protected View messageInputBar;
public View messageInputBar;
protected View messageEditLL;
protected FrameLayout audioTextSwitchLayout;
......@@ -407,10 +406,10 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
//验证用户是否已经绑定手机,若没有绑定则弹出提示
// 账户信息是null时 判断是否是聊天室 不是聊天室提示用户退出重试
if (ActionHandlerStorage.getL(container.account) == null && container.sessionType != SessionTypeEnum.ChatRoom) {
ToastUtil.toastShort("请退出聊天界面重试");
return;
}
// if (ActionHandlerStorage.getL(container.account) == null && container.sessionType != SessionTypeEnum.ChatRoom) {
// ToastUtil.toastShort("请退出聊天界面重试");
// return;
// }
if (v == switchToTextButtonInInputBar) {
switchToTextLayout(true);// 显示文本发送的布局
......@@ -657,7 +656,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
/**
* 隐藏键盘布局
*/
private void hideInputMethod() {
public void hideInputMethod() {
isKeyboardShowed = false;
uiHandler.removeCallbacks(showTextRunnable);
InputMethodManager imm = (InputMethodManager) container.activity.getSystemService(Context.INPUT_METHOD_SERVICE);
......
......@@ -2,6 +2,8 @@ package com.yidianling.uikit.business.session.viewholder;
import android.text.method.LinkMovementMethod;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.yidianling.im.R;
......@@ -16,6 +18,7 @@ public class MsgViewHolderNotification extends MsgViewHolderBase {
}
protected TextView notificationTextView;
protected ImageView ivLabel;
@Override
protected int getContentResId() {
......@@ -25,6 +28,8 @@ public class MsgViewHolderNotification extends MsgViewHolderBase {
@Override
protected void inflateContentView() {
notificationTextView = (TextView) view.findViewById(R.id.message_item_notification_label);
ivLabel = view.findViewById(R.id.iv_label);
}
@Override
......@@ -39,6 +44,12 @@ public class MsgViewHolderNotification extends MsgViewHolderBase {
private void handleTextNotification(String text) {
MoonUtil.identifyFaceExpressionAndATags(context, notificationTextView, text, ImageSpan.ALIGN_BOTTOM);
notificationTextView.setMovementMethod(LinkMovementMethod.getInstance());
if (getDisplayText().contains("群聊已结束")){
ivLabel.setVisibility(View.VISIBLE);
}else {
ivLabel.setVisibility(View.GONE);
}
}
@Override
......
package com.yidianling.uikit.business.team.helper;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.MsgStatusEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.CustomMessageConfig;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.team.TeamService;
import com.netease.nimlib.sdk.team.constant.TeamBeInviteModeEnum;
import com.netease.nimlib.sdk.team.constant.TeamFieldEnum;
import com.netease.nimlib.sdk.team.constant.TeamTypeEnum;
import com.netease.nimlib.sdk.team.model.CreateTeamResult;
import com.netease.nimlib.sdk.team.model.Team;
import com.yidianling.common.tools.LogUtil;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.im.R;
import com.yidianling.im.session.SessionHelper;
import com.yidianling.nimbase.common.ToastHelper;
import com.yidianling.nimbase.common.ui.dialog.DialogMaker;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by hzxuwen on 2015/9/25.
*/
public class TeamCreateHelper {
private static final String TAG = TeamCreateHelper.class.getSimpleName();
private static final int DEFAULT_TEAM_CAPACITY = 200;
/**
* 创建讨论组
*/
public static void createNormalTeam(final Context context, List<String> memberAccounts, final boolean isNeedBack, final RequestCallback<CreateTeamResult> callback) {
String teamName = "讨论组";
DialogMaker.showProgressDialog(context, context.getString(R.string.empty), true);
// 创建群
HashMap<TeamFieldEnum, Serializable> fields = new HashMap<TeamFieldEnum, Serializable>();
fields.put(TeamFieldEnum.Name, teamName);
NIMClient.getService(TeamService.class).createTeam(fields, TeamTypeEnum.Normal, "",
memberAccounts).setCallback(
new RequestCallback<CreateTeamResult>() {
@Override
public void onSuccess(CreateTeamResult result) {
DialogMaker.dismissProgressDialog();
ArrayList<String> failedAccounts = result.getFailedInviteAccounts();
if (failedAccounts != null && !failedAccounts.isEmpty()) {
TeamHelper.onMemberTeamNumOverrun(failedAccounts, context);
} else {
ToastUtil.toastShort("创建群聊成功");
}
if (isNeedBack) {
// SessionHelper.startTeamSession(context, result.getTeam().getId(), MainActivity.class, null); // 进入创建的群
LogUtil.e("进入创建的群:"+result.getTeam().getId());
} else {
SessionHelper.startTeamSession(context, result.getTeam().getId());
}
if (callback != null) {
callback.onSuccess(result);
}
}
@Override
public void onFailed(int code) {
DialogMaker.dismissProgressDialog();
if (code == ResponseCode.RES_TEAM_ECOUNT_LIMIT) {
ToastUtil.toastShort("已达到人数限制");
} else {
ToastUtil.toastShort("创建群聊失败:code="+code);
}
Log.e(TAG, "create team error: " + code);
}
@Override
public void onException(Throwable exception) {
DialogMaker.dismissProgressDialog();
}
}
);
}
/**
* 创建高级群
*/
public static void createAdvancedTeam(final Context context, List<String> memberAccounts) {
String teamName = "高级群";
ToastUtil.toastShort("创建中。。。。");
// 创建群
TeamTypeEnum type = TeamTypeEnum.Advanced;
HashMap<TeamFieldEnum, Serializable> fields = new HashMap<>();
fields.put(TeamFieldEnum.Name, teamName);
fields.put(TeamFieldEnum.BeInviteMode, TeamBeInviteModeEnum.NoAuth);
NIMClient.getService(TeamService.class).createTeam(fields, type, "",
memberAccounts).setCallback(
new RequestCallback<CreateTeamResult>() {
@Override
public void onSuccess(CreateTeamResult result) {
Log.i(TAG, "create team success, team id =" + result.getTeam().getId() + ", now begin to update property...");
onCreateSuccess(context, result);
}
@Override
public void onFailed(int code) {
DialogMaker.dismissProgressDialog();
String tip;
if (code == ResponseCode.RES_TEAM_ECOUNT_LIMIT) {
tip = "邀请失败成员人数上限为200人";
} else if (code == ResponseCode.RES_TEAM_LIMIT) {
tip = "创建失败,创建群数量达到限制";
} else {
tip = "创建失败code:"+code;
}
ToastHelper.showToast(context, tip);
Log.e(TAG, "create team error: " + code);
}
@Override
public void onException(Throwable exception) {
DialogMaker.dismissProgressDialog();
}
}
);
}
/**
* 群创建成功回调
*/
private static void onCreateSuccess(final Context context, CreateTeamResult result) {
if (result == null) {
Log.e(TAG, "onCreateSuccess exception: team is null");
return;
}
final Team team = result.getTeam();
if (team == null) {
Log.e(TAG, "onCreateSuccess exception: team is null");
return;
}
Log.i(TAG, "create and update team success");
DialogMaker.dismissProgressDialog();
// 检查有没有邀请失败的成员
ArrayList<String> failedAccounts = result.getFailedInviteAccounts();
if (failedAccounts != null && !failedAccounts.isEmpty()) {
TeamHelper.onMemberTeamNumOverrun(failedAccounts, context);
} else {
ToastUtil.toastShort("创建高级群成功");
}
// 演示:向群里插入一条Tip消息,使得该群能立即出现在最近联系人列表(会话列表)中,满足部分开发者需求
Map<String, Object> content = new HashMap<>(1);
content.put("content", "成功创建高级群");
IMMessage msg = MessageBuilder.createTipMessage(team.getId(), SessionTypeEnum.Team);
msg.setRemoteExtension(content);
CustomMessageConfig config = new CustomMessageConfig();
config.enableUnreadCount = false;
msg.setConfig(config);
msg.setStatus(MsgStatusEnum.success);
NIMClient.getService(MsgService.class).saveMessageToLocal(msg, true);
// 发送后,稍作延时后跳转
new Handler(context.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
SessionHelper.startTeamSession(context, team.getId()); // 进入创建的群
}
}, 50);
}
}
......@@ -112,19 +112,42 @@
android:textColor="#999999"
android:textSize="11dp" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:layout_marginTop="5dp"
>
<TextView
android:id="@+id/chat_message_content"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/not_disturb"
android:layout_marginEnd="@dimen/platform_dp_10"
android:layout_marginBottom="18dp"
android:layout_marginRight="35dp"
android:layout_marginTop="5dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:layout_toLeftOf="@id/not_disturb"
android:maxLines="1"
android:text="你好,请问你遇到了什么烦恼?我可你好,请问你遇到了什么烦恼?我可以帮…"
android:textColor="#999999"
android:textSize="14dp" />
<ImageView
android:layout_width="@dimen/platform_dp_15"
android:layout_height="@dimen/platform_dp_15"
android:src="@drawable/team_not_disturb"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/chat_message_content"
app:layout_constraintBottom_toBottomOf="@id/chat_message_content"
android:id="@+id/not_disturb"
android:visibility="gone"
>
</ImageView>
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:layout_width="match_parent"
......
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/message_item_notification_label"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dip"
android:layout_marginRight="7dip"
android:orientation="horizontal"
android:background="@drawable/im_nim_bg_message_tip"
android:gravity="center"
android:paddingLeft="7dip"
android:paddingRight="7dip"
>
<ImageView
android:id="@+id/iv_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:src="@drawable/ic_group_chat_end"
/>
<TextView
android:id="@+id/message_item_notification_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:includeFontPadding="false"
android:textColor="#ffffff"
android:textSize="12sp"/>
</LinearLayout>
</merge>
\ No newline at end of file
......@@ -51,12 +51,12 @@
android:layout_gravity="center_horizontal"
android:layout_weight="2"
android:ellipsize="end"
android:singleLine="true"
android:gravity="center"
android:maxEms="12"
android:maxLength="12"
android:maxEms="11"
android:textColor="@color/im_color_242424"
android:textSize="17dp"
tools:text="现现现现现现在在现在在在在现在在" />
tools:text="我是第几个字体马上查看一下" />
<TextView
android:id="@+id/tv_bottom_title"
......
......@@ -607,7 +607,6 @@
android:layout_marginEnd="@dimen/platform_dp_12"
android:layout_marginBottom="@dimen/platform_dp_8"
>
</TextView>
<FrameLayout
android:id="@+id/fl_question_content"
......@@ -615,9 +614,6 @@
android:layout_height="wrap_content"
android:background="@color/white"
android:visibility="gone" />
<include
layout="@layout/im_nim_message_activity_bottom_layout" />
</LinearLayout>
......@@ -88,6 +88,7 @@ dependencies {
api project(':ydl-webview')
api project(':ydl-platform')
api project(":ydl-pay")
// implementation project(":ydl-tuicore")
implementation modularPublication('com.ydl:m-user-api')
implementation modularPublication('com.ydl:m-course-api')
implementation modularPublication('com.ydl:m-im-api')
......@@ -107,5 +108,6 @@ dependencies {
api(rootProject.ext.dependencies["ydl-platform"]) {
transitive = true
}
// implementation rootProject.ext.dependencies["ydl-tuicore"]
}
}
......@@ -325,6 +325,7 @@ public class AccountSettingActivity extends BaseActivity implements View.OnClick
return;
}
userHttp.bindQQ(new BindQQ(map.get("openid"), map.get("unionid")))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(o -> {
dismissProgressDialog();
......
......@@ -4,5 +4,4 @@ include ':app',
':m-home',
':m-consultant', ':m-muse', ':m-fm', ':m-tests', ":m-course",
":m-im",":m-dynamic","m-article","m-audioim","m-user","m-confide"
include ':ydl-tuicore'
......@@ -52,14 +52,14 @@ public class DefaultFormatPrinter {
public void printJsonRequest(@NonNull Request request, @NonNull String bodyString) {
final String requestBody = LINE_SEPARATOR + BODY_TAG + LINE_SEPARATOR + bodyString;
final String tag = getTag(true);
if (!request.url().toString().contains("writeMaiDianData")){
NetLogUtils.debugInfo(tag, REQUEST_UP_LINE);
logLines(tag, new String[]{URL_TAG + request.url()}, false);
logLines(tag, getRequest(request), true);
logLines(tag, requestBody.split(LINE_SEPARATOR), true);
if (!request.url().toString().contains("writemaidiandata")){
NetLogUtils.debugInfo(tag, END_LINE);
}
}
/**
......@@ -70,7 +70,7 @@ public class DefaultFormatPrinter {
public void printFileRequest(@NonNull Request request) {
final String tag = getTag(true);
if (!request.url().toString().contains("writeMaiDianData")){
NetLogUtils.debugInfo(tag, REQUEST_UP_LINE);
logLines(tag, new String[]{URL_TAG + request.url()}, false);
logLines(tag, getRequest(request), true);
......@@ -78,6 +78,8 @@ public class DefaultFormatPrinter {
NetLogUtils.debugInfo(tag, END_LINE);
}
}
/**
* 打印网络响应信息, 当网络响应时 {{@link okhttp3.ResponseBody}} 可以解析的情况
*
......@@ -100,13 +102,14 @@ public class DefaultFormatPrinter {
final String responseBody = LINE_SEPARATOR + BODY_TAG + LINE_SEPARATOR + bodyString;
final String tag = getTag(false);
final String[] urlLine = {URL_TAG + responseUrl, N};
if (!responseUrl.contains("writeMaiDianData")){
NetLogUtils.debugInfo(tag, RESPONSE_UP_LINE);
logLines(tag, urlLine, true);
logLines(tag, getResponse(headers, chainMs, code, isSuccessful, segments, message), true);
logLines(tag, responseBody.split(LINE_SEPARATOR), true);
NetLogUtils.debugInfo(tag, END_LINE);
}
}
/**
* 打印网络响应信息, 当网络响应时 {{@link okhttp3.ResponseBody}} 为 {@code null} 或不可解析的情况
......@@ -124,13 +127,14 @@ public class DefaultFormatPrinter {
@NonNull List<String> segments, @NonNull String message, @NonNull final String responseUrl) {
final String tag = getTag(false);
final String[] urlLine = {URL_TAG + responseUrl, N};
if (!responseUrl.contains("writeMaiDianData")){
NetLogUtils.debugInfo(tag, RESPONSE_UP_LINE);
logLines(tag, urlLine, true);
logLines(tag, getResponse(headers, chainMs, code, isSuccessful, segments, message), true);
logLines(tag, OMITTED_RESPONSE, true);
NetLogUtils.debugInfo(tag, END_LINE);
}
}
/**
* 对 {@code lines} 中的信息进行逐行打印
......
......@@ -89,6 +89,7 @@ dependencies {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib'
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk7'
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-common'
exclude group: 'com.ydl', module: 'pictureselector'
}
api rootProject.ext.dependencies["ydl-utils"]
......
......@@ -190,7 +190,7 @@ class HttpConfig {
return Interceptor {
val request: Request = it.request()
val originalResponse: Response = it.proceed(request)
// if (!appDebug){
if (!appDebug){
val code = originalResponse.code()
// 接口返回错误的情况下,埋点告诉服务器原因
if (code != 200) {
......@@ -222,7 +222,7 @@ class HttpConfig {
AliYunRichLogsHelper.getInstance().sendRichLog(AliYunLogConfig.API, "writeMaiDianDatacode$code:$api---params:$params ---- message:$message")
}
}
// }
}
originalResponse
}
}
......
......@@ -157,6 +157,9 @@ class LogHelper private constructor() {
val agoraRtmLog = getAgoraRTMLog(BaseApp.getApp())
val agoraRtmBackLog = getAgoraRtmBackLog(BaseApp.getApp())
// 腾讯im日志
val tencentLog = getTencentLog(BaseApp.getApp())
if (zipFile.exists()) zipFile.delete()
zipFile.createNewFile()
......@@ -176,6 +179,10 @@ class LogHelper private constructor() {
files.add(agoraRtmBackLog)
}
if (tencentLog.exists()){
files.add(tencentLog)
}
// ZipUtils.toZip(getLogFolder().absolutePath, FileOutputStream(zipFile), true)
ZipUtils.toZip(files, FileOutputStream(zipFile))
return zipFile
......@@ -254,6 +261,12 @@ class LogHelper private constructor() {
return File(agoraRTMLog)
}
// 获取腾讯im日志
private fun getTencentLog(context: Context):File{
val agoraRTMLog = FileUtils.getSDDirectory() + "/Android/data/" + context.packageName + "/files/log/tencent/imsdk"
return File(agoraRTMLog)
}
private object Holder {
val INSTANCE = LogHelper()
......
......@@ -15,6 +15,8 @@ import com.ydl.ydlcommon.adapter.DialogListAdapter;
import com.ydl.ydlcommon.view.FullyLinearLayoutManager;
import com.ydl.ydlcommon.R;
import org.w3c.dom.Text;
import java.util.List;
//import com.yidianling.common.view.FullyLinearLayoutManager;
......@@ -42,6 +44,8 @@ public class ListDialog extends Dialog {
private View contentView; //对话框中间加载的其他布局界面
private DialogListAdapter adapter;
private String last_str; //最后一个按钮
private String titleStr; //标题内容
private OnClickListener Last_btnClickListener;
private int itemTextColor;
......@@ -53,12 +57,17 @@ public class ListDialog extends Dialog {
private ListDialog.Builder.OnItemClickLister mOnItemClickLister;
public Builder(Context context, List<String> mDatas, int itemTextColor,String titleStr) {
this.context = context;
this.mDatas = mDatas;
this.itemTextColor = itemTextColor;
this.titleStr=titleStr;
}
public Builder(Context context, List<String> mDatas, int itemTextColor) {
this.context = context;
this.mDatas = mDatas;
this.itemTextColor = itemTextColor;
}
/**
* 设置对话框界面
*
......@@ -80,7 +89,6 @@ public class ListDialog extends Dialog {
return this;
}
public ListDialog.Builder SetLastStr(String bottom) {
this.last_str = bottom;
return this;
......@@ -129,7 +137,18 @@ public class ListDialog extends Dialog {
layout.findViewById(R.id.last_btn).setVisibility(
View.GONE);
}
if (titleStr!=null){
layout.findViewById(R.id.titleLine).setVisibility(
View.VISIBLE);
layout.findViewById(R.id.title).setVisibility(
View.VISIBLE);
((TextView)layout.findViewById(R.id.title)).setText(titleStr);
}else{
layout.findViewById(R.id.titleLine).setVisibility(
View.GONE);
layout.findViewById(R.id.title).setVisibility(
View.GONE);
}
if (mDatas != null && mDatas.size() > 0) {
RecyclerView dialog_list_rcv = (RecyclerView) layout.findViewById(R.id.dialog_list_rcv);
if (adapter == null) {
......
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