From e1dbc9d38cf98f3b6290420d5bdf881f93fd7fa3 Mon Sep 17 00:00:00 2001 From: 18401019693 Date: Thu, 21 Jul 2022 11:24:15 +0800 Subject: [PATCH] 11111 --- app/src/main/AndroidManifest.xml | 22 - .../java/com/shayu/phonelive/AppContext.java | 97 +- .../phonelive/activity/LauncherActivity.java | 29 +- common/build.gradle | 4 +- .../common/activity/SelectImageActivity.java | 62 +- .../com/yunbao/common/bean/BaseModel.java | 9 + .../yunbao/common/bean/ChatRemarkModel.java | 9 + .../com/yunbao/common/bean/IMLoginModel.java | 437 +++++++++ .../com/yunbao/common/bean/LiangModel.java | 21 + .../java/com/yunbao/common/bean/VipModel.java | 21 + .../yunbao/common/custom/TabButtonGroup.java | 18 +- .../yunbao/common/event/MessageIMEvent.java | 19 + .../yunbao/common/manager/IMLoginManager.java | 73 ++ .../yunbao/common/manager/base/ACache.java | 858 ++++++++++++++++++ .../common/manager/base/BaseCacheManager.java | 406 +++++++++ .../manager/imrongcloud/MessageIMManager.java | 154 ++++ .../imrongcloud/RongcloudIMManager.java | 200 ++++ common/src/main/res/layout/view_title.xml | 11 + .../main/res/mipmap-xxhdpi/btn_more_black.png | Bin 0 -> 1062 bytes live/src/main/AndroidManifest.xml | 13 + .../yunbao/live/activity/LiveActivity.java | 142 +-- .../live/activity/LiveAudienceActivity.java | 12 +- .../activity/MyTUIConversationFragment.java | 50 +- .../live/activity/PDLIiveChatActivity.java | 63 ++ .../activity/PDLiveConversationActivity.java | 183 ++++ .../live/activity/SystemMessageActivity.java | 40 - .../live/adapter/SystemMessageAdapter.java | 1 + .../java/com/yunbao/live/bean/ImUserBean.java | 23 + .../dialog/LiveChatListDialogFragment.java | 68 +- .../yunbao/live/dialog/MenuPopuwWindow.java | 138 +++ .../com/yunbao/live/utils/FileSizeUtil.java | 155 ++++ .../live/views/InputPanelViewHolder.java | 293 ++++++ .../live/views/LiveAudienceViewHolder.java | 80 +- .../live/views/SystemMessageViewHolder.java | 1 - .../main/res/layout/activity_conversation.xml | 24 + live/src/main/res/layout/activity_pd_chat.xml | 14 + .../res/layout/activity_webview_medal.xml | 31 +- .../src/main/res/layout/dialog_live_empty.xml | 16 +- live/src/main/res/layout/view_input_panel.xml | 144 +++ live/src/main/res/layout/view_layout_msg.xml | 19 + live/src/main/res/layout/view_sys_msg.xml | 4 +- live/src/main/res/values/style.xml | 13 + main/src/main/AndroidManifest.xml | 13 +- .../yunbao/main/activity/EntryActivity.java | 12 +- .../yunbao/main/activity/LoginActivity.java | 38 +- .../yunbao/main/activity/MainActivity.java | 332 ++----- .../main/activity/MyWebViewActivity.java | 8 +- .../PDLiveConversationListActivity.java | 222 +++++ .../main/activity/RegisterActivity.java | 24 +- .../main/adapter/SystemMessageAdapter.java | 150 +++ .../event/PDLiveConversationListEvent.java | 19 + .../ConversationIMListManager.java | 128 +++ .../PDLiveCustomConversationProvider.java | 50 + .../main/utils/PDLiveMessageProcessor.java | 20 + .../main/views/MainHomeLiveViewHolder.java | 18 +- .../main/views/SystemMessageViewHolder.java | 47 + .../res/layout/activity_conversation_list.xml | 171 ++++ .../res/layout/rc_conversation_fragment.xml | 106 +++ .../res/layout/rc_conversationlist_item.xml | 134 +++ .../res/layout/rc_extension_input_panel.xml | 115 +++ main/src/main/res/layout/view_homemain.xml | 9 +- .../main/res/layout/view_system_message.xml | 12 + .../res/layout/view_system_message_item.xml | 74 ++ main/src/main/res/values/style.xml | 21 + 64 files changed, 4785 insertions(+), 915 deletions(-) create mode 100644 common/src/main/java/com/yunbao/common/bean/BaseModel.java create mode 100644 common/src/main/java/com/yunbao/common/bean/ChatRemarkModel.java create mode 100644 common/src/main/java/com/yunbao/common/bean/IMLoginModel.java create mode 100644 common/src/main/java/com/yunbao/common/bean/LiangModel.java create mode 100644 common/src/main/java/com/yunbao/common/bean/VipModel.java create mode 100644 common/src/main/java/com/yunbao/common/event/MessageIMEvent.java create mode 100644 common/src/main/java/com/yunbao/common/manager/IMLoginManager.java create mode 100644 common/src/main/java/com/yunbao/common/manager/base/ACache.java create mode 100644 common/src/main/java/com/yunbao/common/manager/base/BaseCacheManager.java create mode 100644 common/src/main/java/com/yunbao/common/manager/imrongcloud/MessageIMManager.java create mode 100644 common/src/main/java/com/yunbao/common/manager/imrongcloud/RongcloudIMManager.java create mode 100644 common/src/main/res/mipmap-xxhdpi/btn_more_black.png create mode 100644 live/src/main/java/com/yunbao/live/activity/PDLIiveChatActivity.java create mode 100644 live/src/main/java/com/yunbao/live/activity/PDLiveConversationActivity.java create mode 100644 live/src/main/java/com/yunbao/live/dialog/MenuPopuwWindow.java create mode 100644 live/src/main/java/com/yunbao/live/utils/FileSizeUtil.java create mode 100644 live/src/main/java/com/yunbao/live/views/InputPanelViewHolder.java create mode 100644 live/src/main/res/layout/activity_conversation.xml create mode 100644 live/src/main/res/layout/activity_pd_chat.xml create mode 100644 live/src/main/res/layout/view_input_panel.xml create mode 100644 live/src/main/res/layout/view_layout_msg.xml create mode 100644 live/src/main/res/values/style.xml create mode 100644 main/src/main/java/com/yunbao/main/activity/PDLiveConversationListActivity.java create mode 100644 main/src/main/java/com/yunbao/main/adapter/SystemMessageAdapter.java create mode 100644 main/src/main/java/com/yunbao/main/event/PDLiveConversationListEvent.java create mode 100644 main/src/main/java/com/yunbao/main/manager/imrongcloud/ConversationIMListManager.java create mode 100644 main/src/main/java/com/yunbao/main/utils/PDLiveCustomConversationProvider.java create mode 100644 main/src/main/java/com/yunbao/main/utils/PDLiveMessageProcessor.java create mode 100644 main/src/main/java/com/yunbao/main/views/SystemMessageViewHolder.java create mode 100644 main/src/main/res/layout/activity_conversation_list.xml create mode 100644 main/src/main/res/layout/rc_conversation_fragment.xml create mode 100644 main/src/main/res/layout/rc_conversationlist_item.xml create mode 100644 main/src/main/res/layout/rc_extension_input_panel.xml create mode 100644 main/src/main/res/layout/view_system_message.xml create mode 100644 main/src/main/res/layout/view_system_message_item.xml create mode 100644 main/src/main/res/values/style.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f6027866f..6e7a18b49 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -112,18 +112,6 @@ - - - - - - - - - - - - - - - - - - - - - - 4) { - firstIndexRM = rongMsg.getContent().substring(0, 5); - } - String firstIndexRM2 = ""; - if (rongMsg.getContent().length() > 9) { - firstIndexRM2 = rongMsg.getContent().substring(0, 10); - } - if ("{\"msg".equals(firstIndexRM) || "{\"retcode\"".equals(firstIndexRM2)) { - liveImDeletUtil.deleteMessages(message.getTargetId(), message.getMessageId()); - } - } - } - } else { - - //私聊 - Message msg = Message.obtain(); - msg.what = Constants.SOCKET_WHAT_BROADCAST; - if (!"".equals(message.getContent()) && message.getContent() != null) { - if (message.getObjectName().equals("RC:TxtMsg")) { - TextMessage content = (TextMessage) message.getContent(); - msg.obj = content.getContent(); - if (content.getContent().contains("_method_")) { - if (SocketRyClient.mSocketHandler != null) { - CommonAppContext.Ingroup = 1; - SocketRyClient.mSocketHandler.sendMessage(msg); - } - } - TextMessage rongMsg = (TextMessage) message.getContent(); - String firstIndexRM = ""; - if (rongMsg.getContent().length() > 4) { - firstIndexRM = rongMsg.getContent().substring(0, 5); - } - String firstIndexRM2 = ""; - if (rongMsg.getContent().length() > 9) { - firstIndexRM2 = rongMsg.getContent().substring(0, 10); - } - if ("{\"msg".equals(firstIndexRM) || "{\"retcode\"".equals(firstIndexRM2)) { - liveImDeletUtil.deleteMessages(message.getTargetId(), message.getMessageId()); - } - } - } - } - - return false; - } + // + RongcloudIMManager.addRongcloudIMOnReceiveMessageListener(); + //初始化融云 + RongcloudIMManager.initRongIM(this); + //添加融云连接状态监听 + RongcloudIMManager.setIMStatusListener(); }); @@ -275,4 +197,9 @@ public class AppContext extends CommonAppContext { return false; } + @Override + public void onTerminate() { + RongcloudIMManager.removeRongcloudIMOnReceiveMessageListener(); + super.onTerminate(); + } } diff --git a/app/src/main/java/com/shayu/phonelive/activity/LauncherActivity.java b/app/src/main/java/com/shayu/phonelive/activity/LauncherActivity.java index 9f4593cfc..7bd0d57ff 100644 --- a/app/src/main/java/com/shayu/phonelive/activity/LauncherActivity.java +++ b/app/src/main/java/com/shayu/phonelive/activity/LauncherActivity.java @@ -6,8 +6,10 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; + import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; + import android.text.TextUtils; import android.util.Log; import android.view.Gravity; @@ -32,12 +34,15 @@ import com.tencent.ugc.TXUGCBase; import com.yunbao.common.CommonAppConfig; import com.yunbao.common.bean.AdBean; import com.yunbao.common.bean.ConfigBean; +import com.yunbao.common.bean.IMLoginModel; import com.yunbao.common.bean.UserBean; import com.yunbao.common.custom.CircleProgress; import com.yunbao.common.glide.ImgLoader; import com.yunbao.common.http.CommonHttpConsts; import com.yunbao.common.http.CommonHttpUtil; import com.yunbao.common.interfaces.CommonCallback; +import com.yunbao.common.manager.IMLoginManager; +import com.yunbao.common.manager.imrongcloud.RongcloudIMManager; import com.yunbao.common.utils.DownloadUtil; import com.yunbao.common.utils.L; import com.yunbao.common.utils.MD5Util; @@ -94,10 +99,6 @@ public class LauncherActivity extends AppCompatActivity implements View.OnClickL protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStatusBar(); -// if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) { -// finish(); -// return; -// } setContentView(R.layout.activity_launcher); //开屏 AdjustEvent adjustEvent = new AdjustEvent("vjqk8g"); @@ -230,20 +231,11 @@ public class LauncherActivity extends AppCompatActivity implements View.OnClickL mHandler.removeCallbacksAndMessages(null); mHandler = null; } - String[] uidAndToken = SpUtil.getInstance().getMultiStringValue( - new String[]{SpUtil.UID, SpUtil.TOKEN}); - final String uid = uidAndToken[0]; - final String token = uidAndToken[1]; - if (!TextUtils.isEmpty(uid) && !TextUtils.isEmpty(token)) { - MainHttpUtil.getBaseInfo(uid, token, new CommonCallback() { - @Override - public void callback(UserBean bean) { - if (bean != null) { - CommonAppConfig.getInstance().setLoginInfo(uid, token, false); - forwardMainActivity(); - } - } - }); + IMLoginModel model = IMLoginManager.get(this).getUserInfo(); + if (model != null) { + //融云连接服务器 + RongcloudIMManager.connectIM(this); + forwardMainActivity(); } else { releaseVideo(); this.startActivity(new Intent(this, EntryActivity.class)); @@ -258,7 +250,6 @@ public class LauncherActivity extends AppCompatActivity implements View.OnClickL private void forwardMainActivity() { releaseVideo(); MainActivity.forward(mContext); -// this.startActivity(new Intent(this, TestActivity.class)); finish(); } diff --git a/common/build.gradle b/common/build.gradle index 6ae3648f4..cf03d4f02 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -152,8 +152,8 @@ dependencies { api 'com.google.code.gson:gson:2.8.8' api 'cn.rongcloud.sdk:rtc_lib:5.2.0' // 音视频通话基础能力库 //此处以集成 5.1.2 版本为例 - api 'cn.rongcloud.sdk:im_lib:5.2.0.2' - + api 'cn.rongcloud.sdk:im_lib:5.1.3.10' // 即时通讯基础能力库 + api 'cn.rongcloud.sdk:im_kit:5.1.3.10' // 即时通讯 UI 基础组件 api 'com.facebook.android:facebook-login:8.2.0' api 'com.facebook.android:facebook-android-sdk:[5,6)' diff --git a/common/src/main/java/com/yunbao/common/activity/SelectImageActivity.java b/common/src/main/java/com/yunbao/common/activity/SelectImageActivity.java index efa66a9b6..4c4ff983f 100644 --- a/common/src/main/java/com/yunbao/common/activity/SelectImageActivity.java +++ b/common/src/main/java/com/yunbao/common/activity/SelectImageActivity.java @@ -13,23 +13,24 @@ import android.os.Bundle; import android.os.Environment; import android.os.Parcelable; import android.provider.MediaStore; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.ActivityCompat; -import androidx.loader.app.LoaderManager; -import androidx.core.content.ContextCompat; -import androidx.loader.content.CursorLoader; -import androidx.core.content.FileProvider; -import androidx.loader.content.Loader; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; +import androidx.loader.app.LoaderManager; +import androidx.loader.content.CursorLoader; +import androidx.loader.content.Loader; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.yunbao.common.R; import com.yunbao.common.adapter.ImageAdapter; import com.yunbao.common.adapter.ImageFolderAdapter; @@ -62,17 +63,11 @@ public class SelectImageActivity extends AbsActivity implements ImageFolderView. public static int MAX_SIZE = 5; private static final int PERMISSION_REQUEST_CODE = 88; private static final int TAKE_PHOTO = 99; - // @BindView(R.id.tv_back) TextView mTvBack; - // @BindView(R.id.tv_ok) TextView mTvSelectCount; - // @BindView(R.id.rv) RecyclerView mRvImage; - // @BindView(R.id.tv_photo) TextView mTvPhoto; - // @BindView(R.id.tv_preview) TextView mTvPreview; - // @BindView(R.id.image_folder_view) ImageFolderView mImageFolderView; View v_back; @@ -180,33 +175,6 @@ public class SelectImageActivity extends AbsActivity implements ImageFolderView. } } -// @OnClick({R.id.tv_back, R.id.tv_ok, R.id.tv_photo, R.id.tv_preview}) -// public void onViewClicked(View view) { -// switch (view.getId()) { -// case R.id.tv_back: -// finish(); -// break; -// case R.id.tv_ok: -// Intent intent = new Intent(); -// intent.putParcelableArrayListExtra(EXTRA_RESULT, (ArrayList) mSelectedImages); -// setResult(RESULT_OK, intent); -// finish(); -// break; -// case R.id.tv_photo: -// if (mImageFolderView.isShowing()) { -// mImageFolderView.hide(); -// } else { -// mImageFolderView.show(); -// } -// break; -// case R.id.tv_preview: -// Intent previewIntent = new Intent(this, PreviewImageActivity.class); -// previewIntent.putParcelableArrayListExtra("preview_images", (ArrayList) mSelectedImages); -// startActivity(previewIntent); -// break; -// } -// } - private void addImageFoldersToAdapter() { if (mImageFolderAdapter == null) { mImageFolderAdapter = new ImageFolderAdapter(this, mImageFolders, R.layout.item_list_folder); @@ -460,12 +428,6 @@ public class SelectImageActivity extends AbsActivity implements ImageFolderView. protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && requestCode == TAKE_PHOTO) { - //缩略图信息是储存在返回的intent中的Bundle中的,对应Bundle中的键为data,因此从Intent中取出 Bundle再根据data取出来Bitmap即可 - // Bundle extras = data.getExtras(); - // Bitmap bitmap = (Bitmap) extras.get("data"); -// BitmapFactory.decodeFile(this.getContentResolver().) -// galleryAddPictures(mImageUri); -// getSupportLoaderManager().restartLoader(0, null, mLoaderCallbacks); galleryAddPictures(); try { Bitmap bitmap = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(mImageUri)); diff --git a/common/src/main/java/com/yunbao/common/bean/BaseModel.java b/common/src/main/java/com/yunbao/common/bean/BaseModel.java new file mode 100644 index 000000000..951f6c08c --- /dev/null +++ b/common/src/main/java/com/yunbao/common/bean/BaseModel.java @@ -0,0 +1,9 @@ +package com.yunbao.common.bean; + +import java.io.Serializable; + +/** + * 数据类基类实现序列化 + */ +public class BaseModel implements Serializable { +} diff --git a/common/src/main/java/com/yunbao/common/bean/ChatRemarkModel.java b/common/src/main/java/com/yunbao/common/bean/ChatRemarkModel.java new file mode 100644 index 000000000..96e9eb146 --- /dev/null +++ b/common/src/main/java/com/yunbao/common/bean/ChatRemarkModel.java @@ -0,0 +1,9 @@ +package com.yunbao.common.bean; + +/** + * 聊天备注信息 + */ +public class ChatRemarkModel extends BaseModel { + private String userId; + private String remarks; +} diff --git a/common/src/main/java/com/yunbao/common/bean/IMLoginModel.java b/common/src/main/java/com/yunbao/common/bean/IMLoginModel.java new file mode 100644 index 000000000..a0e843545 --- /dev/null +++ b/common/src/main/java/com/yunbao/common/bean/IMLoginModel.java @@ -0,0 +1,437 @@ +package com.yunbao.common.bean; + +import com.google.gson.annotations.SerializedName; + +/** + * 登录账号的数据类型(和com.yunbao.common.bean.UserBean重复分别单独使用,后续优化去掉其中一个) + */ +public class IMLoginModel extends BaseModel { + + /** + * avatar : https://napi.yaoulive.com/default.jpg + * avatar_thumb : https://napi.yaoulive.com/default_thumb.jpg + * birthday : + * city : + * coin : 0 + * consumption : 10200 + * front_task : 0 + * gold : 1020 + * goldsumption : 0 + * goodnum : + * id : 146267 + * issuper : 0 + * langue : chinese + * level : 6 + * level_anchor : 1 + * liang : {"name":"0"} + * location : + * medal_level : 0 + * medal_name : + * noble_id : 0 + * province : + * sex : 1 + * signature : 这家伙很懒,什么都没留下 + * token : 857706071fb09255b370eaf18d152d69 + * token_rong : PT2F9Czs6EdhMRnO1KKIZx0w4VLHhDYtXuIXO7PWfrA=@xln2.sg.rongnav.com;xln2.sg.rongcfg.com + * user_nicename : 测试03 + * user_status : 1 + * vip : {"type":"0"} + * votestotal : 0 + */ + //用户头像 + @SerializedName("avatar") + private String avatar = ""; + //头像缩略图 + @SerializedName("avatar_thumb") + private String avatarThumb = ""; + //用户生日 + @SerializedName("birthday") + private String birthday = ""; + //用户城市 + @SerializedName("city") + private String city = ""; + // + @SerializedName("coin") + private long coin = 0; + // + @SerializedName("consumption") + private long consumption = 0; + // + @SerializedName("front_task") + private long frontTask = 0; + // + @SerializedName("gold") + private long gold = 0; + // + @SerializedName("goldsumption") + private long goldsumption = 0; + // + @SerializedName("goodnum") + private String goodnum = ""; + //用户ID唯一识别标志 + @SerializedName("id") + private long id = 0; + // + @SerializedName("issuper") + private long issuper = 0; + // + @SerializedName("langue") + private String langue = ""; + // + @SerializedName("level") + private String level = ""; + // + @SerializedName("level_anchor") + private String levelAnchor = ""; + // + @SerializedName("liang") + private LiangModel liang = new LiangModel(); + // + @SerializedName("location") + private String location = ""; + // + @SerializedName("medal_level") + private String medalLevel = ""; + // + @SerializedName("medal_name") + private String medalName = ""; + // + @SerializedName("noble_id") + private long nobleId = 0; + // + @SerializedName("province") + private String province = ""; + //性别 + @SerializedName("sex") + private long sex = 0; + // + @SerializedName("signature") + private String signature = ""; + //平台token + @SerializedName("token") + private String token = ""; + //融云token(由服务器维护) + @SerializedName("token_rong") + private String tokenRong = ""; + //昵称 + @SerializedName("user_nicename") + private String userNicename = ""; + // + @SerializedName("user_status") + private long userStatus = 0; + // + @SerializedName("vip") + private VipModel vip = new VipModel(); + // + @SerializedName("votestotal") + private long votestotal = 0; + //是否首次登录 + @SerializedName("first_login") + private long firstLogin = 0; + // + @SerializedName("isagent") + private long isagent = 0; + //未读消息数(只在MessageIMManager中使用) + @SerializedName("num") + private String num = ""; + //是否是管理员 + @SerializedName("is_admin") + private String isAdmin = ""; + + public String getIsAdmin() { + return isAdmin; + } + + public IMLoginModel setIsAdmin(String isAdmin) { + this.isAdmin = isAdmin; + return this; + } + + public String getNum() { + return num; + } + + public IMLoginModel setNum(String num) { + this.num = num; + return this; + } + + public long getFirstLogin() { + return firstLogin; + } + + public IMLoginModel setFirstLogin(long firstLogin) { + this.firstLogin = firstLogin; + return this; + } + + public long getIsagent() { + return isagent; + } + + public IMLoginModel setIsagent(long isagent) { + this.isagent = isagent; + return this; + } + + public String getAvatar() { + return avatar; + } + + public IMLoginModel setAvatar(String avatar) { + this.avatar = avatar; + return this; + } + + public String getAvatarThumb() { + return avatarThumb; + } + + public IMLoginModel setAvatarThumb(String avatarThumb) { + this.avatarThumb = avatarThumb; + return this; + } + + public String getBirthday() { + return birthday; + } + + public IMLoginModel setBirthday(String birthday) { + this.birthday = birthday; + return this; + } + + public String getCity() { + return city; + } + + public IMLoginModel setCity(String city) { + this.city = city; + return this; + } + + public long getCoin() { + return coin; + } + + public IMLoginModel setCoin(long coin) { + this.coin = coin; + return this; + } + + public long getConsumption() { + return consumption; + } + + public IMLoginModel setConsumption(long consumption) { + this.consumption = consumption; + return this; + } + + public long getFrontTask() { + return frontTask; + } + + public IMLoginModel setFrontTask(long frontTask) { + this.frontTask = frontTask; + return this; + } + + public long getGold() { + return gold; + } + + public IMLoginModel setGold(long gold) { + this.gold = gold; + return this; + } + + public long getGoldsumption() { + return goldsumption; + } + + public IMLoginModel setGoldsumption(long goldsumption) { + this.goldsumption = goldsumption; + return this; + } + + public String getGoodnum() { + return goodnum; + } + + public IMLoginModel setGoodnum(String goodnum) { + this.goodnum = goodnum; + return this; + } + + public long getId() { + return id; + } + + public IMLoginModel setId(long id) { + this.id = id; + return this; + } + + public long getIssuper() { + return issuper; + } + + public IMLoginModel setIssuper(long issuper) { + this.issuper = issuper; + return this; + } + + public String getLangue() { + return langue; + } + + public IMLoginModel setLangue(String langue) { + this.langue = langue; + return this; + } + + public String getLevel() { + return level; + } + + public IMLoginModel setLevel(String level) { + this.level = level; + return this; + } + + public String getLevelAnchor() { + return levelAnchor; + } + + public IMLoginModel setLevelAnchor(String levelAnchor) { + this.levelAnchor = levelAnchor; + return this; + } + + public LiangModel getLiang() { + return liang; + } + + public IMLoginModel setLiang(LiangModel liang) { + this.liang = liang; + return this; + } + + public String getLocation() { + return location; + } + + public IMLoginModel setLocation(String location) { + this.location = location; + return this; + } + + public String getMedalLevel() { + return medalLevel; + } + + public IMLoginModel setMedalLevel(String medalLevel) { + this.medalLevel = medalLevel; + return this; + } + + public String getMedalName() { + return medalName; + } + + public IMLoginModel setMedalName(String medalName) { + this.medalName = medalName; + return this; + } + + public long getNobleId() { + return nobleId; + } + + public IMLoginModel setNobleId(long nobleId) { + this.nobleId = nobleId; + return this; + } + + public String getProvince() { + return province; + } + + public IMLoginModel setProvince(String province) { + this.province = province; + return this; + } + + public long getSex() { + return sex; + } + + public IMLoginModel setSex(long sex) { + this.sex = sex; + return this; + } + + public String getSignature() { + return signature; + } + + public IMLoginModel setSignature(String signature) { + this.signature = signature; + return this; + } + + public String getToken() { + return token; + } + + public IMLoginModel setToken(String token) { + this.token = token; + return this; + } + + public String getTokenRong() { + return tokenRong; + } + + public IMLoginModel setTokenRong(String tokenRong) { + this.tokenRong = tokenRong; + return this; + } + + public String getUserNicename() { + return userNicename; + } + + public IMLoginModel setUserNicename(String userNicename) { + this.userNicename = userNicename; + return this; + } + + public long getUserStatus() { + return userStatus; + } + + public IMLoginModel setUserStatus(long userStatus) { + this.userStatus = userStatus; + return this; + } + + public VipModel getVip() { + return vip; + } + + public IMLoginModel setVip(VipModel vip) { + this.vip = vip; + return this; + } + + public long getVotestotal() { + return votestotal; + } + + public IMLoginModel setVotestotal(long votestotal) { + this.votestotal = votestotal; + return this; + } +} diff --git a/common/src/main/java/com/yunbao/common/bean/LiangModel.java b/common/src/main/java/com/yunbao/common/bean/LiangModel.java new file mode 100644 index 000000000..72e59b113 --- /dev/null +++ b/common/src/main/java/com/yunbao/common/bean/LiangModel.java @@ -0,0 +1,21 @@ +package com.yunbao.common.bean; + +import com.google.gson.annotations.SerializedName; + +public class LiangModel extends BaseModel { + /** + * name : 0 + */ + + @SerializedName("name") + private String name = ""; + + public String getName() { + return name; + } + + public LiangModel setName(String name) { + this.name = name; + return this; + } +} diff --git a/common/src/main/java/com/yunbao/common/bean/VipModel.java b/common/src/main/java/com/yunbao/common/bean/VipModel.java new file mode 100644 index 000000000..535c7dd08 --- /dev/null +++ b/common/src/main/java/com/yunbao/common/bean/VipModel.java @@ -0,0 +1,21 @@ +package com.yunbao.common.bean; + +import com.google.gson.annotations.SerializedName; + +public class VipModel extends BaseModel { + /** + * type : 0 + */ + + @SerializedName("type") + private String type = ""; + + public String getType() { + return type; + } + + public VipModel setType(String type) { + this.type = type; + return this; + } +} diff --git a/common/src/main/java/com/yunbao/common/custom/TabButtonGroup.java b/common/src/main/java/com/yunbao/common/custom/TabButtonGroup.java index c0fc8de1c..6f8d14c52 100644 --- a/common/src/main/java/com/yunbao/common/custom/TabButtonGroup.java +++ b/common/src/main/java/com/yunbao/common/custom/TabButtonGroup.java @@ -1,8 +1,10 @@ package com.yunbao.common.custom; import android.content.Context; + import androidx.annotation.Nullable; import androidx.viewpager.widget.ViewPager; + import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; @@ -54,7 +56,6 @@ public class TabButtonGroup extends LinearLayout implements View.OnClickListener public void setCurPosition(int position) { //点击事件切换 if (position == mCurPosition) { -// return; long curTime = System.currentTimeMillis(); if (curTime - mLastClickBackTime <= 500) { if (position != 2 && position != 3) { @@ -80,6 +81,9 @@ public class TabButtonGroup extends LinearLayout implements View.OnClickListener Object tag = v.getTag(); if (tag != null) { setCurPosition((int) tag); + if (listener != null) { + listener.onPageSelected(v, (int) tag); + } } } @@ -92,11 +96,19 @@ public class TabButtonGroup extends LinearLayout implements View.OnClickListener for (TabButton tbn : mTabButtons) { if (tbn != null) { tbn.cancelAnim(); - - } } } } + public interface TabButtonGroupChangeListener { + void onPageSelected(View view, int index); + } + + private TabButtonGroupChangeListener listener = null; + + public void addTabButtonGroupChangeListener(TabButtonGroupChangeListener mListener) { + listener = mListener; + } + } diff --git a/common/src/main/java/com/yunbao/common/event/MessageIMEvent.java b/common/src/main/java/com/yunbao/common/event/MessageIMEvent.java new file mode 100644 index 000000000..39aeed9f9 --- /dev/null +++ b/common/src/main/java/com/yunbao/common/event/MessageIMEvent.java @@ -0,0 +1,19 @@ +package com.yunbao.common.event; + +import com.yunbao.common.bean.BaseModel; + +/** + * 未读消息整合 + */ +public class MessageIMEvent extends BaseModel { + private int number = 0; + + public int getNumber() { + return number; + } + + public MessageIMEvent setNumber(int number) { + this.number = number; + return this; + } +} diff --git a/common/src/main/java/com/yunbao/common/manager/IMLoginManager.java b/common/src/main/java/com/yunbao/common/manager/IMLoginManager.java new file mode 100644 index 000000000..03ba23e9f --- /dev/null +++ b/common/src/main/java/com/yunbao/common/manager/IMLoginManager.java @@ -0,0 +1,73 @@ +package com.yunbao.common.manager; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.yunbao.common.bean.IMLoginModel; +import com.yunbao.common.manager.base.BaseCacheManager; + +/** + * 登录者信息管理 + */ +public class IMLoginManager extends BaseCacheManager { + + + private final static String KEY_USER_INFO = "keyUserInfo"; + + private static IMLoginManager manager; + private IMLoginModel userInfo; + + private IMLoginManager(Context context) { + super(context); + } + + /** + * 获取单利 + * + * @return + */ + public static IMLoginManager get(Context context) { + if (null == manager) { + manager = new IMLoginManager(context); + } + return manager; + } + + /** + * 获取用户信息 + * + * @return + */ + public IMLoginModel getUserInfo() { + if (null == userInfo) { + userInfo = new Gson().fromJson( + getString(KEY_USER_INFO), IMLoginModel.class); + } + return userInfo; + } + + /** + * 设置已登录的用户信息 + * + * @param model + */ + public void setupLoginUser(@NonNull IMLoginModel model) { + put(KEY_USER_INFO, new Gson().toJson(model)); + this.userInfo = model; + + } + + /** + * 退出登录 + */ + public void logout() { + //删除用户登录信息 + deleteByKey(KEY_USER_INFO); + //用户对象置空 + userInfo=null; + manager = null; + } + +} diff --git a/common/src/main/java/com/yunbao/common/manager/base/ACache.java b/common/src/main/java/com/yunbao/common/manager/base/ACache.java new file mode 100644 index 000000000..11fb7b2ea --- /dev/null +++ b/common/src/main/java/com/yunbao/common/manager/base/ACache.java @@ -0,0 +1,858 @@ +/** + * Copyright (c) 2012-2013, Michael Yang 杨福海 (www.yangfuhai.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.yunbao.common.manager.base; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.PixelFormat; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.RandomAccessFile; +import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/** + * android轻量级缓存框架 + */ +public class ACache { + public static final int TIME_HOUR = 60 * 60; + public static final int TIME_DAY = TIME_HOUR * 24; + private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb + private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放数据的数量 + private static Map mInstanceMap = new HashMap<>(); + private ACacheManager mCache; + + public static ACache get(Context ctx) { + return get(ctx, "ACache"); + } + + public static ACache get(Context ctx, String cacheName) { + File f = new File(ctx.getCacheDir(), cacheName); + return get(f, MAX_SIZE, MAX_COUNT); + } + + public static ACache get(File cacheDir) { + return get(cacheDir, MAX_SIZE, MAX_COUNT); + } + + public static ACache get(Context ctx, long max_zise, int max_count) { + File f = new File(ctx.getCacheDir(), "ACache"); + return get(f, max_zise, max_count); + } + + public static ACache get(File cacheDir, long max_zise, int max_count) { + ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid()); + if (manager == null) { + manager = new ACache(cacheDir, max_zise, max_count); + mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager); + } + return manager; + } + + private static String myPid() { + return "_" + android.os.Process.myPid(); + } + + private ACache(File cacheDir, long max_size, int max_count) { + if (!cacheDir.exists() && !cacheDir.mkdirs()) { + throw new RuntimeException("can't make dirs in " + + cacheDir.getAbsolutePath()); + } + mCache = new ACacheManager(cacheDir, max_size, max_count); + } + + // ======================================= + // ============ String数据 读写 ============== + // ======================================= + + /** + * 保存 String数据 到 缓存中 + * + * @param key 保存的key + * @param value 保存的String数据 + */ + public void put(String key, String value) { + File file = mCache.newFile(key); + BufferedWriter out = null; + try { + out = new BufferedWriter(new FileWriter(file), 1024); + out.write(value); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (out != null) { + try { + out.flush(); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + mCache.put(file); + } + } + + /** + * 保存 String数据 到 缓存中 + * + * @param key 保存的key + * @param value 保存的String数据 + * @param saveTime 保存的时间,单位:秒 + */ + public void put(String key, String value, int saveTime) { + if (saveTime != -1) { + put(key, Utils.newStringWithDateInfo(saveTime, value)); + } else { + put(key, value); + } + } + + /** + * 读取 String数据 + * + * @param key 键 + * @return String 数据 + */ + public String getAsString(String key) { + File file = mCache.get(key); + if (!file.exists()) + return null; + boolean removeFile = false; + BufferedReader in = null; + try { + in = new BufferedReader(new FileReader(file)); + String readString = ""; + String currentLine; + while ((currentLine = in.readLine()) != null) { + readString += currentLine; + } + if (!Utils.isDue(readString)) { + return Utils.clearDateInfo(readString); + } else { + removeFile = true; + return null; + } + } catch (IOException e) { + e.printStackTrace(); + return null; + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (removeFile) + remove(key); + } + } + + // ======================================= + // ============= JSONObject 数据 读写 ============== + // ======================================= + + /** + * 保存 JSONObject数据 到 缓存中 + * + * @param key 保存的key + * @param value 保存的JSON数据 + */ + public void put(String key, JSONObject value) { + put(key, value.toString()); + } + + /** + * 保存 JSONObject数据 到 缓存中 + * + * @param key 保存的key + * @param value 保存的JSONObject数据 + * @param saveTime 保存的时间,单位:秒 + */ + public void put(String key, JSONObject value, int saveTime) { + if (saveTime != -1) { + put(key, value.toString(), saveTime); + } else { + put(key, value.toString()); + } + } + + /** + * 读取JSONObject数据 + * + * @param key 键 + * @return JSONObject数据 + */ + public JSONObject getAsJSONObject(String key) { + String JSONString = getAsString(key); + try { + JSONObject obj = new JSONObject(JSONString); + return obj; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + // ======================================= + // ============ JSONArray 数据 读写 ============= + // ======================================= + + /** + * 保存 JSONArray数据 到 缓存中 + * + * @param key 保存的key + * @param value 保存的JSONArray数据 + */ + public void put(String key, JSONArray value) { + put(key, value.toString()); + } + + /** + * 保存 JSONArray数据 到 缓存中 + * + * @param key 保存的key + * @param value 保存的JSONArray数据 + * @param saveTime 保存的时间,单位:秒 + */ + public void put(String key, JSONArray value, int saveTime) { + if (saveTime != -1) { + put(key, value.toString(), saveTime); + } else { + put(key, value.toString()); + } + } + + /** + * 读取JSONArray数据 + * + * @param key 键 + * @return JSONArray数据 + */ + public JSONArray getAsJSONArray(String key) { + String JSONString = getAsString(key); + try { + JSONArray obj = new JSONArray(JSONString); + return obj; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + // ======================================= + // ============== byte 数据 读写 ============= + // ======================================= + + /** + * 保存 byte数据 到 缓存中 + * + * @param key 保存的key + * @param value 保存的数据 + */ + public void put(String key, byte[] value) { + File file = mCache.newFile(key); + FileOutputStream out = null; + try { + out = new FileOutputStream(file); + out.write(value); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (out != null) { + try { + out.flush(); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + mCache.put(file); + } + } + + /** + * 保存 byte数据 到 缓存中 + * + * @param key 保存的key + * @param value 保存的数据 + * @param saveTime 保存的时间,单位:秒 + */ + public void put(String key, byte[] value, int saveTime) { + if (saveTime != -1) { + put(key, Utils.newByteArrayWithDateInfo(saveTime, value)); + } else { + put(key, value); + } + } + + /** + * 获取 byte 数据 + * + * @param key 键 + * @return byte 数据 + */ + public byte[] getAsBinary(String key) { + RandomAccessFile RAFile = null; + boolean removeFile = false; + try { + File file = mCache.get(key); + if (!file.exists()) + return null; + RAFile = new RandomAccessFile(file, "r"); + byte[] byteArray = new byte[(int) RAFile.length()]; + RAFile.read(byteArray); + if (!Utils.isDue(byteArray)) { + return Utils.clearDateInfo(byteArray); + } else { + removeFile = true; + return null; + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + if (RAFile != null) { + try { + RAFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (removeFile) + remove(key); + } + } + + // ======================================= + // ============= 序列化 数据 读写 =============== + // ======================================= + + /** + * 保存 Serializable数据 到 缓存中 + * + * @param key 保存的key + * @param value 保存的value + */ + public void put(String key, Serializable value) { + put(key, value, -1); + } + + /** + * 保存 Serializable数据到 缓存中 + * + * @param key 保存的key + * @param value 保存的value + * @param saveTime 保存的时间,单位:秒 + */ + public void put(String key, Serializable value, int saveTime) { + ByteArrayOutputStream baos = null; + ObjectOutputStream oos = null; + try { + baos = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(baos); + oos.writeObject(value); + byte[] data = baos.toByteArray(); + if (saveTime != -1) { + put(key, data, saveTime); + } else { + put(key, data); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + oos.close(); + } catch (IOException e) { + } + } + } + + /** + * 读取 Serializable数据 + * + * @param key key + * @return Serializable 数据 + */ + public Object getAsObject(String key) { + byte[] data = getAsBinary(key); + if (data != null) { + ByteArrayInputStream bais = null; + ObjectInputStream ois = null; + try { + bais = new ByteArrayInputStream(data); + ois = new ObjectInputStream(bais); + Object reObject = ois.readObject(); + return reObject; + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + try { + if (bais != null) + bais.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (ois != null) + ois.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + + } + + // ======================================= + // ============== bitmap 数据 读写 ============= + // ======================================= + + /** + * 保存 bitmap 到 缓存中 + * + * @param key 保存的key + * @param value 保存的bitmap数据 + */ + public void put(String key, Bitmap value) { + put(key, Utils.Bitmap2Bytes(value)); + } + + /** + * 保存 bitmap 到 缓存中 + * + * @param key 保存的key + * @param value 保存的 bitmap 数据 + * @param saveTime 保存的时间,单位:秒 + */ + public void put(String key, Bitmap value, int saveTime) { + put(key, Utils.Bitmap2Bytes(value), saveTime); + } + + /** + * 读取 bitmap 数据 + * + * @param key key + * @return bitmap 数据 + */ + public Bitmap getAsBitmap(String key) { + if (getAsBinary(key) == null) { + return null; + } + return Utils.Bytes2Bimap(getAsBinary(key)); + } + + // ======================================= + // ============= drawable 数据 读写 ============= + // ======================================= + + /** + * 保存 drawable 到 缓存中 + * + * @param key 保存的key + * @param value 保存的drawable数据 + */ + public void put(String key, Drawable value) { + put(key, Utils.drawable2Bitmap(value)); + } + + /** + * 保存 drawable 到 缓存中 + * + * @param key 保存的key + * @param value 保存的 drawable 数据 + * @param saveTime 保存的时间,单位:秒 + */ + public void put(String key, Drawable value, int saveTime) { + put(key, Utils.drawable2Bitmap(value), saveTime); + } + + /** + * 读取 Drawable 数据 + * + * @param key key + * @return Drawable 数据 + */ + public Drawable getAsDrawable(String key) { + if (getAsBinary(key) == null) { + return null; + } + return Utils.bitmap2Drawable(Utils.Bytes2Bimap(getAsBinary(key))); + } + + /** + * 获取缓存文件 + * + * @param key key + * @return value 缓存的文件 + */ + public File file(String key) { + File f = mCache.newFile(key); + if (f.exists()) + return f; + return null; + } + + /** + * 移除某个key + * + * @param key key + * @return 是否移除成功 + */ + public boolean remove(String key) { + return mCache.remove(key); + } + + /** + * 清除所有数据 + */ + public void clear() { + mCache.clear(); + } + + /** + * @author 杨福海(michael) www.yangfuhai.com + * @version 1.0 + */ + public class ACacheManager { + private final AtomicLong cacheSize; + private final AtomicInteger cacheCount; + private final long sizeLimit; + private final int countLimit; + private final Map lastUsageDates = Collections + .synchronizedMap(new HashMap()); + protected File cacheDir; + + private ACacheManager(File cacheDir, long sizeLimit, int countLimit) { + this.cacheDir = cacheDir; + this.sizeLimit = sizeLimit; + this.countLimit = countLimit; + cacheSize = new AtomicLong(); + cacheCount = new AtomicInteger(); + calculateCacheSizeAndCacheCount(); + } + + /** + * 计算 cacheSize和cacheCount + */ + private void calculateCacheSizeAndCacheCount() { + new Thread(new Runnable() { + @Override + public void run() { + int size = 0; + int count = 0; + File[] cachedFiles = cacheDir.listFiles(); + if (cachedFiles != null) { + for (File cachedFile : cachedFiles) { + size += calculateSize(cachedFile); + count += 1; + lastUsageDates.put(cachedFile, + cachedFile.lastModified()); + } + cacheSize.set(size); + cacheCount.set(count); + } + } + }).start(); + } + + private void put(File file) { + int curCacheCount = cacheCount.get(); + while (curCacheCount + 1 > countLimit) { + long freedSize = removeNext(); + cacheSize.addAndGet(-freedSize); + + curCacheCount = cacheCount.addAndGet(-1); + } + cacheCount.addAndGet(1); + + long valueSize = calculateSize(file); + long curCacheSize = cacheSize.get(); + while (curCacheSize + valueSize > sizeLimit) { + long freedSize = removeNext(); + curCacheSize = cacheSize.addAndGet(-freedSize); + } + cacheSize.addAndGet(valueSize); + + Long currentTime = System.currentTimeMillis(); + file.setLastModified(currentTime); + lastUsageDates.put(file, currentTime); + } + + private File get(String key) { + File file = newFile(key); + Long currentTime = System.currentTimeMillis(); + file.setLastModified(currentTime); + lastUsageDates.put(file, currentTime); + + return file; + } + + private File newFile(String key) { + return new File(cacheDir, key.hashCode() + ""); + } + + private boolean remove(String key) { + File image = get(key); + return image.delete(); + } + + private void clear() { + lastUsageDates.clear(); + cacheSize.set(0); + File[] files = cacheDir.listFiles(); + if (files != null) { + for (File f : files) { + f.delete(); + } + } + } + + /** + * 移除旧的文件 + * + * @return + */ + private long removeNext() { + if (lastUsageDates.isEmpty()) { + return 0; + } + + Long oldestUsage = null; + File mostLongUsedFile = null; + Set> entries = lastUsageDates.entrySet(); + synchronized (lastUsageDates) { + for (Entry entry : entries) { + if (mostLongUsedFile == null) { + mostLongUsedFile = entry.getKey(); + oldestUsage = entry.getValue(); + } else { + Long lastValueUsage = entry.getValue(); + if (lastValueUsage < oldestUsage) { + oldestUsage = lastValueUsage; + mostLongUsedFile = entry.getKey(); + } + } + } + } + + long fileSize = calculateSize(mostLongUsedFile); + if (mostLongUsedFile.delete()) { + lastUsageDates.remove(mostLongUsedFile); + } + return fileSize; + } + + private long calculateSize(File file) { + return file.length(); + } + } + + /** + * @author 杨福海(michael) www.yangfuhai.com + * @version 1.0 + * @title 时间计算工具类 + */ + private static class Utils { + + /** + * 判断缓存的String数据是否到期 + * + * @param str key + * @return true:到期了 false:还没有到期 + */ + private static boolean isDue(String str) { + return isDue(str.getBytes()); + } + + /** + * 判断缓存的byte数据是否到期 + * + * @param data 数据集合 + * @return true:到期了 false:还没有到期 + */ + private static boolean isDue(byte[] data) { + String[] strs = getDateInfoFromDate(data); + if (strs != null && strs.length == 2) { + String saveTimeStr = strs[0]; + while (saveTimeStr.startsWith("0")) { + saveTimeStr = saveTimeStr + .substring(1, saveTimeStr.length()); + } + long saveTime = Long.valueOf(saveTimeStr); + long deleteAfter = Long.valueOf(strs[1]); + if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) { + return true; + } + } + return false; + } + + private static String newStringWithDateInfo(int second, String strInfo) { + return createDateInfo(second) + strInfo; + } + + private static byte[] newByteArrayWithDateInfo(int second, byte[] data2) { + byte[] data1 = createDateInfo(second).getBytes(); + byte[] retdata = new byte[data1.length + data2.length]; + System.arraycopy(data1, 0, retdata, 0, data1.length); + System.arraycopy(data2, 0, retdata, data1.length, data2.length); + return retdata; + } + + private static String clearDateInfo(String strInfo) { + if (strInfo != null && hasDateInfo(strInfo.getBytes())) { + strInfo = strInfo.substring(strInfo.indexOf(mSeparator) + 1, + strInfo.length()); + } + return strInfo; + } + + private static byte[] clearDateInfo(byte[] data) { + if (hasDateInfo(data)) { + return copyOfRange(data, indexOf(data, mSeparator) + 1, + data.length); + } + return data; + } + + private static boolean hasDateInfo(byte[] data) { + return data != null && data.length > 15 && data[13] == '-' + && indexOf(data, mSeparator) > 14; + } + + private static String[] getDateInfoFromDate(byte[] data) { + if (hasDateInfo(data)) { + String saveDate = new String(copyOfRange(data, 0, 13)); + String deleteAfter = new String(copyOfRange(data, 14, + indexOf(data, mSeparator))); + return new String[]{saveDate, deleteAfter}; + } + return null; + } + + private static int indexOf(byte[] data, char c) { + for (int i = 0; i < data.length; i++) { + if (data[i] == c) { + return i; + } + } + return -1; + } + + private static byte[] copyOfRange(byte[] original, int from, int to) { + int newLength = to - from; + if (newLength < 0) + throw new IllegalArgumentException(from + " > " + to); + byte[] copy = new byte[newLength]; + System.arraycopy(original, from, copy, 0, + Math.min(original.length - from, newLength)); + return copy; + } + + private static final char mSeparator = ' '; + + private static String createDateInfo(int second) { + String currentTime = System.currentTimeMillis() + ""; + while (currentTime.length() < 13) { + currentTime = "0" + currentTime; + } + return currentTime + "-" + second + mSeparator; + } + + /* + * Bitmap → byte[] + */ + private static byte[] Bitmap2Bytes(Bitmap bm) { + if (bm == null) { + return null; + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + bm.compress(Bitmap.CompressFormat.PNG, 100, baos); + return baos.toByteArray(); + } + + /* + * byte[] → Bitmap + */ + private static Bitmap Bytes2Bimap(byte[] b) { + if (b.length == 0) { + return null; + } + return BitmapFactory.decodeByteArray(b, 0, b.length); + } + + /* + * Drawable → Bitmap + */ + private static Bitmap drawable2Bitmap(Drawable drawable) { + if (drawable == null) { + return null; + } + // 取 drawable 的长宽 + int w = drawable.getIntrinsicWidth(); + int h = drawable.getIntrinsicHeight(); + // 取 drawable 的颜色格式 + Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 + : Bitmap.Config.RGB_565; + // 建立对应 bitmap + Bitmap bitmap = Bitmap.createBitmap(w, h, config); + // 建立对应 bitmap 的画布 + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, w, h); + // 把 drawable 内容画到画布中 + drawable.draw(canvas); + return bitmap; + } + + /* + * Bitmap → Drawable + */ + @SuppressWarnings("deprecation") + private static Drawable bitmap2Drawable(Bitmap bm) { + if (bm == null) { + return null; + } + return new BitmapDrawable(bm); + } + } + +} \ No newline at end of file diff --git a/common/src/main/java/com/yunbao/common/manager/base/BaseCacheManager.java b/common/src/main/java/com/yunbao/common/manager/base/BaseCacheManager.java new file mode 100644 index 000000000..7869114d9 --- /dev/null +++ b/common/src/main/java/com/yunbao/common/manager/base/BaseCacheManager.java @@ -0,0 +1,406 @@ +package com.yunbao.common.manager.base; + +import android.content.Context; +import android.content.SharedPreferences; +import android.text.TextUtils; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.Serializable; +import java.lang.reflect.Type; +import java.util.List; + +/** + * 缓存管理基类 + */ +public class BaseCacheManager { + private int mode; + private Gson gson; + private ACache aCache; + private Context context; + private SharedPreferences sharedPreferences; + + public BaseCacheManager(Context context) { + this(context, Context.MODE_PRIVATE); + } + + public BaseCacheManager(Context context, int mode) { + this.context = context; + this.mode = mode; + } + + /** + * 懒加载acache对象 + * + * @return 当前类对象 + */ + private ACache getACache() { + if (null == aCache) { + this.aCache = ACache.get(context, getCacheName()); + } + return aCache; + } + + /** + * 懒加载SharedPreferences对象 + * + * @return sp对象 + */ + private SharedPreferences getSharedPreferences() { + if (null == sharedPreferences) { + this.sharedPreferences = context.getSharedPreferences(getCacheName(), mode); + } + return sharedPreferences; + } + + /** + * 懒加载Gson对象 + * + * @return gson对象 + */ + private Gson getGson() { + if (null == gson) {//首次获取gson + this.gson = getCustomizeGson(); + if (null == gson) {//为空则创建默认gson + this.gson = new Gson(); + } + } + return gson; + } + + /** + * 插入byte[]类型 + * + * @param key 键 + * @param value 值 + */ + public void put(String key, Byte[] value) { + put(key, value, -1); + } + + /** + * 插入byte[]类型 + * + * @param key 键 + * @param value 值 + * @param saveTime 存储时间 + */ + public void put(String key, Byte[] value, int saveTime) { + getACache().put(key, value, saveTime); + } + + /** + * 插入string类型 + * + * @param key 键 + * @param value 值 + */ + public void put(String key, String value) { + put(key, value, -1); + } + + /** + * 插入string类型 + * + * @param key 键 + * @param value 值 + * @param saveTime 存储时间 + */ + public void put(String key, String value, int saveTime) { + getACache().put(key, value, saveTime); + } + + /** + * 插入实现了serializable接口的对象 + * + * @param key 键 + * @param value 值 + * @param 泛型 + */ + public void put(String key, D value) { + put(key, value, -1); + } + + /** + * 插入实现了serializable接口的对象 + * + * @param key 键 + * @param value 值 + * @param 泛型 + * @param saveTime 存储时间 + */ + public void put(String key, D value, int saveTime) { + getACache().put(key, value, saveTime); + } + + /** + * 插入jsonobject对象 + * + * @param key 键 + * @param value 值 + */ + public void put(String key, JSONObject value) { + put(key, value, -1); + } + + /** + * 插入jsonobject对象 + * + * @param key 键 + * @param value 值 + * @param saveTime 存储时间 + */ + public void put(String key, JSONObject value, int saveTime) { + getACache().put(key, value, saveTime); + } + + /** + * 插入jsonarray对象 + * + * @param key 键 + * @param value 值 + */ + public void put(String key, JSONArray value) { + put(key, value, -1); + } + + /** + * 插入jsonarray对象 + * + * @param key 键 + * @param value 值 + * @param saveTime 存储时间 + */ + public void put(String key, JSONArray value, int saveTime) { + getACache().put(key, value, saveTime); + } + + /** + * 插入一个集合 + * + * @param key 键 + * @param values 值 + * @param 泛型 + * @return 是否插入成功 + */ + public boolean put(String key, List values) { + return put(key, values, -1); + } + + /** + * 插入一个集合,使用gson解析为jsonarray进行存储,可能会出现很多对象不兼容的问题 + * + * @param key 键 + * @param values 值 + * @param saveTime 存储时间 + * @param 泛型 + * @return 是否存储成功 + */ + public boolean put(String key, List values, int saveTime) { + String json = getGson().toJson(values); + if (!TextUtils.isEmpty(json)) { + getACache().put(key, json, saveTime); + } + return false; + } + + /** + * 插入int类型数据 + * + * @param key 键 + * @param value 值 + * @return 是否存储成功 + */ + public boolean put(String key, int value) { + return getSharedPreferences() + .edit() + .putInt(key, value) + .commit(); + } + + /** + * 插入boolean类型数据 + * + * @param key 键 + * @param value 值 + * @return 是否存储成功 + */ + public boolean put(String key, boolean value) { + return getSharedPreferences() + .edit() + .putBoolean(key, value) + .commit(); + } + + /** + * 插入float类型 + * + * @param key 键 + * @param value 值 + * @return 是否存储成功 + */ + public boolean put(String key, float value) { + return getSharedPreferences() + .edit() + .putFloat(key, value) + .commit(); + } + + /** + * 插入long类型 + * + * @param key 键 + * @param value 值 + * @return 是否存储成功 + */ + public boolean put(String key, long value) { + return getSharedPreferences() + .edit() + .putLong(key, value) + .commit(); + } + + /** + * 根据key删除文件 + * + * @param key 键 + * @return 是否删除成功 + */ + public boolean deleteByKey(@NonNull String key) { + return getACache().remove(key) || getSharedPreferences() + .edit() + .remove(key) + .commit(); + } + + /** + * 查byte[]类型 + * + * @param key 键 + * @return 获取byte数组 + */ + public byte[] getBinary(@NonNull String key) { + return getACache().getAsBinary(key); + } + + /** + * 差String类型 + * + * @param key 键 + * @return 获取存储的string 类型值 + */ + public String getString(@NonNull String key) { + return getACache().getAsString(key); + } + + /** + * 查询实现了Serializable的对象 + * + * @param key 键 + * @param 泛型 + * @return 序列化的对象 + */ + public R getSerializable(@NonNull String key) { + return (R) getACache().getAsObject(key); + } + + /** + * 查询jsonobject + * + * @param key 键 + * @return jsonobject对象 + */ + public JSONObject getJsonObject(@NonNull String key) { + return getACache().getAsJSONObject(key); + } + + /** + * 查询jsonarray + * + * @param key 键 + * @return jsonarray集合 + */ + public JSONArray getJsonArray(@NonNull String key) { + return getACache().getAsJSONArray(key); + } + + /** + * 获取一个集合 + * + * @param key 键 + * @param typeOfT 类别 + * @param 泛型 + * @return 集合 + */ + public List getList(@NonNull String key, Type typeOfT) { + JSONArray jsonArray = getJsonArray(key); + return getGson().fromJson(null != jsonArray ? jsonArray.toString() : "[]", typeOfT); + } + + /** + * 查询int + * + * @param key 键 + * @param defValut 默认值 + * @return int值 + */ + public int getInt(@NonNull String key, int defValut) { + return getSharedPreferences().getInt(key, defValut); + } + + /** + * 查询boolean + * + * @param key 键 + * @param defValue 默认值 + * @return 布尔值 + */ + public boolean getBoolean(@NonNull String key, boolean defValue) { + return getSharedPreferences().getBoolean(key, defValue); + } + + /** + * 查询float + * + * @param key 键 + * @param defValue 默认值 + * @return float值 + */ + public float getFloat(@NonNull String key, float defValue) { + return getSharedPreferences().getFloat(key, defValue); + } + + /** + * 查询long + * + * @param key 键 + * @param defVlaue 默认值 + * @return long值 + */ + public long getLong(@NonNull String key, long defVlaue) { + return getSharedPreferences().getLong(key, defVlaue); + } + + /** + * 获取缓存路径名 + * + * @return 获取存储路径名 + */ + public String getCacheName() { + return "jtechCache"; + } + + /** + * 获取定制gson,使用者可以重写,不为空则会使用当前返回 + * + * @return 获取自定义的gson + */ + public Gson getCustomizeGson() { + return new Gson(); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/yunbao/common/manager/imrongcloud/MessageIMManager.java b/common/src/main/java/com/yunbao/common/manager/imrongcloud/MessageIMManager.java new file mode 100644 index 000000000..8d1e0e73c --- /dev/null +++ b/common/src/main/java/com/yunbao/common/manager/imrongcloud/MessageIMManager.java @@ -0,0 +1,154 @@ +package com.yunbao.common.manager.imrongcloud; + +import android.content.Context; +import android.os.Handler; +import android.text.TextUtils; + +import com.alibaba.fastjson.JSON; +import com.yunbao.common.bean.IMLoginModel; +import com.yunbao.common.event.MessageIMEvent; +import com.yunbao.common.http.HttpCallback; +import com.yunbao.common.http.HttpClient; +import com.yunbao.common.manager.IMLoginManager; + +import org.greenrobot.eventbus.EventBus; + +import java.util.Arrays; +import java.util.List; + +import io.rong.imkit.manager.UnReadMessageManager; +import io.rong.imlib.model.Conversation; + +/** + * 消息的监听管理 + */ +public class MessageIMManager { + private static MessageIMManager manager; + private Context mContext; + //Handler统一管理系统和融云的未读消息 + private Handler unreadMessagesHandler = new Handler(); + private int number = 0, imNumber = 0, systemNumber = 0; + + public MessageIMManager(Context mContext) { + this.mContext = mContext; + number = 0; + } + + /** + * 获取单利 + */ + public static MessageIMManager get(Context context) { + if (null == manager) { + manager = new MessageIMManager(context); + } + return manager; + } + + /** + * 添加融云消息监听 + */ + public void addImRongCloudObserver() { +// //只监听私聊消息 + Conversation.ConversationType[] conversationTypes = {Conversation.ConversationType.PRIVATE}; + UnReadMessageManager.getInstance().addObserver(conversationTypes, new UnReadMessageManager.IUnReadMessageObserver() { + @Override + public void onCountChanged(int integer) { + imNumber = integer; + //发送通知 + unreadMessagesHandler.post(essagesRunnable); + } + }); + + } + + /** + * 获取系统消息(有未读数展示红点) + */ + public void getSystemMessages() { + IMLoginModel userInfo = IMLoginManager.get(mContext).getUserInfo(); + HttpClient.getInstance().get("Message.getLists", "getImUserInfo") + .params("uid", userInfo.getId()) + .params("token", userInfo.getToken()) + .execute(new HttpCallback() { + @Override + public void onSuccess(int code, String msg, String[] info) { + if (code == 0) { + List listUserBean = JSON.parseArray(Arrays.toString(info), IMLoginModel.class); + if (listUserBean != null && listUserBean.size() >= 2) { + //目前就三条消息,需求判断前两条消息是否有未读消息 + for (int i = 0; i < listUserBean.size() - 2; i++) { + //消息对象 + IMLoginModel userBean = listUserBean.get(i); + //未读消息数 + String number = userBean.getNum(); + //未读消息不为空并且大于0 + try { + if (!TextUtils.isEmpty(number) && Integer.parseInt(number) > 0) { + systemNumber = Integer.parseInt(number); + } + } catch (NumberFormatException e) { + systemNumber = 0; + } + } + //发送通知 + unreadMessagesHandler.post(essagesRunnable); + } + } + } + }); + } + + /** + * 获取系统消息(有未读数展示红点) + */ + public void getSystemMessages(SystemMessagesHttpCallback callback) { + IMLoginModel userInfo = IMLoginManager.get(mContext).getUserInfo(); + HttpClient.getInstance().get("Message.getLists", "getImUserInfo") + .params("uid", userInfo.getId()) + .params("token", userInfo.getToken()) + .execute(new HttpCallback() { + @Override + public void onSuccess(int code, String msg, String[] info) { + if (callback != null) { + callback.onSuccess(code, msg, info); + } + if (code == 0) { + List listUserBean = JSON.parseArray(Arrays.toString(info), IMLoginModel.class); + if (listUserBean != null && listUserBean.size() >= 2) { + //目前就三条消息,需求判断前两条消息是否有未读消息 + for (int i = 0; i < listUserBean.size() - 2; i++) { + //消息对象 + IMLoginModel userBean = listUserBean.get(i); + //未读消息数 + String number = userBean.getNum(); + //未读消息不为空并且大于0 + try { + if (!TextUtils.isEmpty(number) && Integer.parseInt(number) > 0) { + systemNumber = Integer.parseInt(number); + } + } catch (NumberFormatException e) { + systemNumber = 0; + } + } + //发送通知 + unreadMessagesHandler.post(essagesRunnable); + } + } + } + }); + } + + /** + * 系统消息的数据回传接口 + */ + public interface SystemMessagesHttpCallback { + void onSuccess(int code, String msg, String[] info); + } + + //整合未读消息数目并且发送出去 + private final Runnable essagesRunnable = () -> { + number = imNumber + systemNumber; + EventBus.getDefault().postSticky(new MessageIMEvent().setNumber(number)); + }; + +} diff --git a/common/src/main/java/com/yunbao/common/manager/imrongcloud/RongcloudIMManager.java b/common/src/main/java/com/yunbao/common/manager/imrongcloud/RongcloudIMManager.java new file mode 100644 index 000000000..399475ef6 --- /dev/null +++ b/common/src/main/java/com/yunbao/common/manager/imrongcloud/RongcloudIMManager.java @@ -0,0 +1,200 @@ +package com.yunbao.common.manager.imrongcloud; + +import android.app.Application; +import android.content.Context; +import android.util.Log; +import android.widget.ImageView; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.CircleCrop; +import com.bumptech.glide.request.RequestOptions; +import com.yunbao.common.bean.IMLoginModel; +import com.yunbao.common.manager.IMLoginManager; + +import io.rong.imkit.GlideKitImageEngine; +import io.rong.imkit.IMCenter; +import io.rong.imkit.RongIM; +import io.rong.imkit.config.RongConfigCenter; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.model.Conversation; +import io.rong.imlib.model.Message; + +/** + * 会话列表 + * 融云即时通讯的管理类 + */ +public class RongcloudIMManager { + //融云开发者平台注册app唯一识别符 + private static final String RONG_IM_KEY = "uwd1c0sxu1p71"; + private static final String CLASSNAME = "RongcloudIMManager"; + + /** + * 融云初始化 + * + * @param application 应用上下文 + */ + public static void initRongIM(Application application) { + //第三个参数代表是否开启推送 + RongIM.init(application, RONG_IM_KEY, true); + Log.e(CLASSNAME, "initRongIM:"); + initPhotoGlide(); + } + + private static RongIMClient.OnReceiveMessageWrapperListener listener = new RongIMClient.OnReceiveMessageWrapperListener() { + @Override + public boolean onReceived(Message message, int left, boolean hasPackage, boolean offline) { + return false; + } + }; + + /** + * 设置消息接受监听器 + */ + public static void addRongcloudIMOnReceiveMessageListener() { + IMCenter.getInstance().addOnReceiveMessageListener(listener); + } + + /** + * 移除消息接受监听器 + */ + public static void removeRongcloudIMOnReceiveMessageListener() { + IMCenter.getInstance().removeOnReceiveMessageListener(listener); + } + + /** + * 修改聊天列表头像为圆形 + */ + private static void initPhotoGlide() { + RongConfigCenter.featureConfig().setKitImageEngine(new GlideKitImageEngine() { + @Override + public void loadConversationListPortrait(@NonNull Context context, + @NonNull String url, + @NonNull ImageView imageView, + Conversation conversation) { + Glide.with(imageView).load(url) + .apply(RequestOptions.bitmapTransform(new CircleCrop())) + .into(imageView); + } + + @Override + public void loadConversationPortrait(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, Message message) { + Glide.with(imageView).load(url) + .apply(RequestOptions.bitmapTransform(new CircleCrop())) + .into(imageView); + } + }); + + } + + /** + * 连接融云服务器 + * + * @param context + */ + public static void connectIM(Context context) { + MessageIMManager.get(context).addImRongCloudObserver(); + MessageIMManager.get(context).getSystemMessages(); + IMLoginModel userInfo = IMLoginManager.get(context).getUserInfo(); + String IMToken = userInfo.getTokenRong(); + Log.e(CLASSNAME, "connectIM:" + IMToken); + //参数注解:IMToken :从服务端获取的 Token + //timeLimit :超时时间(秒)。超时后不再重连。取值 <=0 则将一直连接,直到连接成功或者发生业务错误。 + //connectCallback : 连接回调。 + RongIM.connect(IMToken, 0, new RongIMClient.ConnectCallback() { + @Override + public void onSuccess(String s) { + //连接成功,如果 onDatabaseOpened() 时没有页面跳转,也可在此时进行跳转。 + Log.e(CLASSNAME, "onSuccess:" + s); + + } + + @Override + public void onError(RongIMClient.ConnectionErrorCode connectionErrorCode) { + if (connectionErrorCode.equals(RongIMClient.ConnectionErrorCode.RC_CONN_TOKEN_EXPIRE)) { + //从 APP 服务请求新 token,获取到新 token 后重新 connect() + Log.e(CLASSNAME, "onError:(从 APP 服务请求新 token)" + RongIMClient.ConnectionErrorCode.RC_CONN_TOKEN_EXPIRE); + } else if (connectionErrorCode.equals(RongIMClient.ConnectionErrorCode.RC_CONNECT_TIMEOUT)) { + //连接超时,弹出提示,可以引导用户等待网络正常的时候再次点击进行连接 + Log.e(CLASSNAME, "onError:(连接超时)" + RongIMClient.ConnectionErrorCode.RC_CONNECT_TIMEOUT); + } else { + //其它业务错误码,请根据相应的错误码作出对应处理。 + Log.e(CLASSNAME, "onError:(其它业务错误码)" + connectionErrorCode); + } + } + + @Override + public void onDatabaseOpened(RongIMClient.DatabaseOpenStatus databaseOpenStatus) { + if (RongIMClient.DatabaseOpenStatus.DATABASE_OPEN_SUCCESS.equals(databaseOpenStatus)) { + //本地数据库打开,跳转到会话列表页面 + Log.e(CLASSNAME, "onDatabaseOpened:(本地数据库打开)" + databaseOpenStatus); + } else { + //数据库打开失败,可以弹出 toast 提示。 + Log.e(CLASSNAME, "onDatabaseOpened:(数据库打开失败)" + databaseOpenStatus); + } + } + }); + } + + /** + * 设置监听 IM 连接状态 + * 建议在应用生命周期中设置 + */ + public static void setIMStatusListener() { + RongIM.setConnectionStatusListener(connectionStatusListener); + } + + /** + * 监听 IM 连接状态,可根据连接状态进行不同业务处理 + */ + private static RongIMClient.ConnectionStatusListener connectionStatusListener = new RongIMClient.ConnectionStatusListener() { + @Override + public void onChanged(ConnectionStatus status) { + Log.e(CLASSNAME, "ConnectionStatusListener:(登录状态监听)" + status.getMessage()); + //开发者需要根据连接状态码,进行不同业务处理 + switch (status) { + //用户主动断开连接的状态,见断开连接 + case SIGN_OUT: + break; + //用户账号在其它设备登录,此设备被踢下线 + case KICKED_OFFLINE_BY_OTHER_CLIENT: + break; + //连接暂时挂起(多是由于网络问题导致),SDK 会在合适时机进行自动重连 + case SUSPEND: + break; + //连接成功 + case CONNECTED: + break; + //连接超时,SDK 将停止连接,用户需要做超时处理,再自行调用连接接口进行连接 + case TIMEOUT: + break; + //连接中 + case CONNECTING: + break; + // 网络不可用 + case NETWORK_UNAVAILABLE: + break; + //未连接状态,即应用没有调用过连接方法 + case UNCONNECTED: + + break; + //Token 过期时触发此状态 + case TOKEN_INCORRECT: + break; + //用户被开发者后台封禁 + case CONN_USER_BLOCKED: + break; + } + } + }; + + /** + * 注销登录信息,有新消息时不再收到任何通知提醒 + */ + public static void logoutIM() { + RongIM.getInstance().logout(); + } + + +} diff --git a/common/src/main/res/layout/view_title.xml b/common/src/main/res/layout/view_title.xml index dbb315a52..620bb7cfc 100644 --- a/common/src/main/res/layout/view_title.xml +++ b/common/src/main/res/layout/view_title.xml @@ -29,5 +29,16 @@ android:src="@mipmap/icon_back" android:tint="@color/textColor" /> + + diff --git a/common/src/main/res/mipmap-xxhdpi/btn_more_black.png b/common/src/main/res/mipmap-xxhdpi/btn_more_black.png new file mode 100644 index 0000000000000000000000000000000000000000..082acac437fd7667d2262d1eb8c9ac7b91093fec GIT binary patch literal 1062 zcmeAS@N?(olHy`uVBq!ia0vp^?jX#;1|&l_M9DKSFu(P5aSW-5dppg)L&jC4y?*`k z{@upS=hm6+zI=7Fq{|U!zjaj?CRYevab4ULXEU>-gYm0^qDmFdi-XwHGA_=t=>Q&OM2`Af^Bz8R0*9nO4wtY+&Dl=#EZVOe))$@31N zggm3+@&4IgWDMQUd{kC=_M>p}JmqIVX%?XFyi3LF+ATkS{%meG`|O07%{r&`q?7d+ z6ZYFO>FVlk-K?|wXj;hXtBL#X|G#Q{ns2d2SDxCUp9&mhmrd@<@wM-tepWlzZ~gVz zGkw(hg)UxZNMaCWn7&Epch}5t_U427s^X4bE1xs0Vd&72Ns}}9Jl$nWR?pAHK5@J6 z=9$kvE6#9-Ux8%<^8)?^-|X6LK4F;_UMr_F&S4CgJ?lhN@w%|pwwK?3UvH(S6yUX% z(Sk`~hSX%niv0BS=SSDBU8}8E+1=fpxHRY|!vW@N^IqC0RT+Cu3Xk3N@7npT7p}Pm ze&G52U`r}|u6gorDz(kA{j%io+mdd6JfV*j_U`95m%^MPQe&z|tj8#Y{6 z6SkV4u|nv;U4}Bo7!{@JyLFGb()9It4j--B`%j@kok51pfU#g+$F;Pyw0&i)$)CLr zYkq$G|9e#9yuJc%BEEapouY Y-a6&*%@dMaf%%`o)78&qol`;+0JeerFaQ7m literal 0 HcmV?d00001 diff --git a/live/src/main/AndroidManifest.xml b/live/src/main/AndroidManifest.xml index 8bb0f285a..eb00d57dd 100644 --- a/live/src/main/AndroidManifest.xml +++ b/live/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + + + + \ No newline at end of file diff --git a/live/src/main/java/com/yunbao/live/activity/LiveActivity.java b/live/src/main/java/com/yunbao/live/activity/LiveActivity.java index e3b03c3bb..161fe26d9 100644 --- a/live/src/main/java/com/yunbao/live/activity/LiveActivity.java +++ b/live/src/main/java/com/yunbao/live/activity/LiveActivity.java @@ -6,7 +6,9 @@ import android.content.ClipboardManager; import android.content.Intent; import android.os.Bundle; import android.os.Handler; + import androidx.fragment.app.DialogFragment; + import android.text.TextUtils; import android.util.Log; import android.view.View; @@ -16,6 +18,7 @@ import android.widget.TextView; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.tencent.imsdk.conversation.ConversationManager; import com.yunbao.common.CommonAppConfig; import com.yunbao.common.Constants; import com.yunbao.common.activity.AbsActivity; @@ -88,6 +91,8 @@ import org.greenrobot.eventbus.ThreadMode; import java.util.HashSet; import java.util.List; +import io.rong.imkit.utils.RouteUtils; + /** * Created by cxf on 2018/10/7. */ @@ -108,9 +113,6 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL protected LiveLinkMicAnchorPresenter mLiveLinkMicAnchorPresenter;//主播与主播连麦逻辑 protected LiveLinkMicPkPresenter mLiveLinkMicPkPresenter;//主播与主播PK逻辑 public static LiveRyLinkMicPkPresenter mLiveRyLinkMicPkPresenter;//主播与主播PK逻辑 - - // public static LiveLinkMicDrPkPresenter liveLinkMicDrPkPresenter;//多人PK -// protected GamePresenter mGamePresenter; public static SocketClient mSocketClient; public static SocketRyClient mSocketRyClient; @@ -129,7 +131,6 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL protected KeyBoardHeightUtil2 mKeyBoardHeightUtil; protected int mChatLevel;//发言等级限制 protected int mDanMuLevel;//弹幕等级限制 - // private MobShareUtil mMobShareUtil; private ProcessImageUtil mImageUtil; private boolean mFirstConnectSocket;//是否是第一次连接成功socket private boolean mGamePlaying;//是否在游戏中 @@ -301,16 +302,6 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL */ @Override public void onSendGift(LiveReceiveGiftBean bean) { -// if (bean.isAllServerNotify()){ -// if (!mIsAnchor){ -// if (mLiveRoomViewHolder != null) { -// //全服通知时,不显示聊天列表里面的 送礼 消息 -// //mLiveRoomViewHolder.insertChat(bean.getLiveChatBean()); -// mLiveRoomViewHolder.showGiftMessage(bean); -// } -// } -// } -// else //购买守护 if (bean.ismTypeBuyGuard()) { @@ -867,16 +858,10 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL @Override public void onGameNz(JSONObject obj) { -// if (mGamePresenter != null) { -// mGamePresenter.onGameNzSocket(obj); -// } } @Override public void onGameEbb(JSONObject obj) { -// if (mGamePresenter != null) { -// mGamePresenter.onGameEbbSocket(obj); -// } } /** @@ -898,7 +883,6 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL fragment.setArguments(bundle); fragment.show(getSupportFragmentManager(), "LiveInputDialogFragment"); } else { -// ToastUtil.show(getResources().getString(R.string.live_issend)); showTaskDialog(); } } @@ -934,40 +918,12 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL * 打开私信列表窗口 */ public void openChatListWindow() { - LiveChatListDialogFragment fragment = new LiveChatListDialogFragment(); - if (!mIsAnchor) { - Bundle bundle = new Bundle(); - bundle.putString(Constants.LIVE_UID, mLiveUid); - fragment.setArguments(bundle); - } - fragment.show(getSupportFragmentManager(), "LiveChatListDialogFragment"); + RouteUtils.registerActivity(RouteUtils.RongActivityType.ConversationActivity, PDLIiveChatActivity.class); + Intent intent = new Intent(mContext, PDLIiveChatActivity.class); + mContext.startActivity(intent); } - /** - * 打开私信聊天窗口 - */ - public void openChatRoomWindow(UserBean userBean, boolean following) { - ConfigBean configBean = CommonAppConfig.getInstance().getConfig(); - if (configBean == null) { - return; - } - int letterSwitch = configBean.getPriMsgSwitch(); - if (letterSwitch == 0) { - ToastUtil.show("私信功能暂不可用"); - return; - } - if (mKeyBoardHeightUtil == null) { - mKeyBoardHeightUtil = new KeyBoardHeightUtil2(mContext, super.findViewById(android.R.id.content), this); - mKeyBoardHeightUtil.start(); - } - LiveChatRoomDialogFragment fragment = new LiveChatRoomDialogFragment(); - fragment.setImageUtil(mImageUtil); - Bundle bundle = new Bundle(); - bundle.putParcelable(Constants.USER_BEAN, userBean); - bundle.putBoolean(Constants.FOLLOW, following); - fragment.setArguments(bundle); - fragment.show(getSupportFragmentManager(), "LiveChatRoomDialogFragment"); - } + /** * 发 弹幕 消息 @@ -1041,14 +997,6 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL // } } - /** - * 发 送礼物 消息 - */ -// public void sendGiftMessage(LiveGiftBean giftBean, String giftToken) { -// int guardType = mLiveGuardInfo != null ? mLiveGuardInfo.getMyGuardType() : Constants.GUARD_TYPE_NONE; -// -// SocketChatUtil.sendGiftMessage(giftBean.getType(), giftToken, mLiveUid,guardType,"0"); -// } /** * 发 送礼物 消息 增加主播名字 @@ -1286,28 +1234,6 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL } - /** - * 分享直播间 - */ -// public void shareLive(String type, MobCallback callback) { -// ConfigBean configBean = CommonAppConfig.getInstance().getConfig(); -// if (configBean == null) { -// return; -// } -// if (mMobShareUtil == null) { -// mMobShareUtil = new MobShareUtil(); -// } -// ShareData data = new ShareData(); -// data.setTitle(configBean.getLiveShareTitle()); -// data.setDes(mLiveBean.getUserNiceName() + configBean.getLiveShareDes()); -// data.setImgUrl(mLiveBean.getAvatarThumb()); -// String webUrl = configBean.getDownloadApkUrl(); -// if (Constants.MOB_WX.equals(type) || Constants.MOB_WX_PYQ.equals(type)) { -// webUrl = configBean.getLiveWxShareUrl() + mLiveUid; -// } -// data.setWebUrl(webUrl); -// mMobShareUtil.execute(type, data, callback); -// } /** * 监听关注变化事件 @@ -1321,23 +1247,6 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL } } - /** - * 监听私信未读消息数变化事件 - */ -// @Subscribe(threadMode = ThreadMode.MAIN) -// public void onImUnReadCountEvent(ImUnReadCountEvent e) { -// String unReadCount = e.getUnReadCount(); -// if (!TextUtils.isEmpty(unReadCount) && mLiveBottomViewHolder != null) { -// mLiveBottomViewHolder.setUnReadCount(unReadCount); -// } -// } - - /** - * 获取私信未读消息数量 - */ -// protected String getImUnReadCount() { -// return ImMessageUtil.getInstance().getAllUnReadMsgCount(); -// } /** * 监听钻石数量变化事件 @@ -1351,9 +1260,6 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL } public void onCoinChanged(String coin) { -// if (mGamePresenter != null) { -// mGamePresenter.setLastCoin(coin); -// } } /** @@ -1388,20 +1294,6 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL fragment.show(getSupportFragmentManager(), "LiveGuardDialogFragment"); } - /** - * 打開在线粉絲團 - */ - public void openFansListWindow() { - - LiveFansFragment fragment = new LiveFansFragment(); - Bundle bundle = new Bundle(); - - //粉絲團粉絲團 - //不是粉絲 - bundle.putString(Constants.URL, CommonAppConfig.HOST + "/h5/live/fansRank.html" + "?uid=" + CommonAppConfig.getInstance().getUid() + "&token=" + CommonAppConfig.getInstance().getToken() + "&anchorUid=" + mLiveUid); - fragment.setArguments(bundle); - fragment.show(getSupportFragmentManager(), "LiveGuardDialogFragment"); - } /** * 打开观看列表弹窗 @@ -1496,19 +1388,9 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL * 打开幸运礼物说明 */ public void openLuckGiftTip() { -// if (mLiveLuckGiftTipViewHolder == null) { UserBean u = CommonAppConfig.getInstance().getUserBean(); String url = CommonAppConfig.HOST + "/h5/Nobility.html?nickname=" + u.getUserNiceName() + "&usernobId=" + u.getNoble_id() + "&token=" + CommonAppConfig.getInstance().getToken() + "&uid=" + CommonAppConfig.getInstance().getUid() + "&anchorUid=" + mLiveUid + "&anchorName=" + mAncherName; startActivity(new Intent(this, ZhuangBanActivity.class).putExtra("url", url)); - Log.e("aaa", url); -// mLiveLuckGiftTipViewHolder = new LiveWebViewHolder(mContext, mPageContainer,url); -// mLiveLuckGiftTipViewHolder.subscribeActivityLifeCycle(); -// mLiveLuckGiftTipViewHolder.addToParent(); -// } -// mLiveLuckGiftTipViewHolder.show(); -// if (CommonAppConfig.LIVE_ROOM_SCROLL && !mIsAnchor) { -// ((LiveAudienceActivity) this).setScrollFrozen(true); -// } } /** @@ -1621,15 +1503,9 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL if (mLiveLuckGiftTipViewHolder != null) { mLiveLuckGiftTipViewHolder.release(); } -// if (mMobShareUtil != null) { -// mMobShareUtil.release(); -// } if (mImageUtil != null) { mImageUtil.release(); } -// if (mGamePresenter != null) { -// mGamePresenter.release(); -// } if (mLiveRoomViewHolder.mHandler != null) { mLiveRoomViewHolder.mHandler.removeCallbacksAndMessages(null); } diff --git a/live/src/main/java/com/yunbao/live/activity/LiveAudienceActivity.java b/live/src/main/java/com/yunbao/live/activity/LiveAudienceActivity.java index be9e1affb..64a1016ab 100644 --- a/live/src/main/java/com/yunbao/live/activity/LiveAudienceActivity.java +++ b/live/src/main/java/com/yunbao/live/activity/LiveAudienceActivity.java @@ -1182,17 +1182,9 @@ public class LiveAudienceActivity extends LiveActivity { @Override protected void onResume() { super.onResume(); - if (mLiveAudienceViewHolder != null) { - mLiveAudienceViewHolder.getChatPoint(); - } + } - //红点(消息中心) - @Subscribe(threadMode = ThreadMode.MAIN) - public void onUpdateFieldEvent(UpdateTablePoint updateTablePoint) { - if (mLiveAudienceViewHolder != null) { - mLiveAudienceViewHolder.getChatPoint(); - } - } + } diff --git a/live/src/main/java/com/yunbao/live/activity/MyTUIConversationFragment.java b/live/src/main/java/com/yunbao/live/activity/MyTUIConversationFragment.java index 4050c2e66..ebd8fc05a 100644 --- a/live/src/main/java/com/yunbao/live/activity/MyTUIConversationFragment.java +++ b/live/src/main/java/com/yunbao/live/activity/MyTUIConversationFragment.java @@ -8,11 +8,6 @@ import android.media.RingtoneManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.cardview.widget.CardView; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import android.text.TextUtils; import android.util.Log; import android.view.Gravity; @@ -23,6 +18,12 @@ import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.TextView; +import androidx.annotation.Nullable; +import androidx.cardview.widget.CardView; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.adjust.sdk.Adjust; import com.adjust.sdk.AdjustEvent; import com.alibaba.fastjson.JSON; @@ -57,12 +58,9 @@ import java.util.Collections; import java.util.Date; import java.util.List; -import io.rong.imlib.RongCoreClient; import io.rong.imlib.RongIMClient; -import io.rong.imlib.listener.OnReceiveMessageWrapperListener; import io.rong.imlib.model.Conversation; import io.rong.imlib.model.Message; -import io.rong.imlib.model.ReceivedProfile; import io.rong.message.RecallNotificationMessage; import io.rong.message.TextMessage; @@ -156,8 +154,6 @@ public class MyTUIConversationFragment extends Fragment { ImHttpUtil.cancel(ImHttpConsts.GET_SYSTEM_MESSAGE_LIST); ImHttpUtil.cancel(ImHttpConsts.GET_IM_USER_INFO); - RongCoreClient.removeOnReceiveMessageListener(listener); - listener = null; } private void initView() { @@ -172,14 +168,14 @@ public class MyTUIConversationFragment extends Fragment { mAdapter.setActionListener(new ImListAdapter.ActionListener() { @Override public void onItemClick(ImUserBean bean) { - if(bean.getContent().equals("在線客服")){ + if (bean.getContent().equals("在線客服")) { mFirebaseAnalytics.logEvent("FS_customer_service", null); logger.logEvent("FB_customer_service"); AdjustEvent adjustEvent1 = new AdjustEvent("ww5z2p"); Adjust.trackEvent(adjustEvent1); - }else if(bean.getContent().equals("新手指導員")){ + } else if (bean.getContent().equals("新手指導員")) { mFirebaseAnalytics.logEvent("FS_guide", null); logger.logEvent("FB_guide", null); AdjustEvent adjustEvent1 = new AdjustEvent("m0nfpn"); @@ -209,7 +205,6 @@ public class MyTUIConversationFragment extends Fragment { }); mRecyclerView.setAdapter(mAdapter); - RongCoreClient.addOnReceiveMessageListener(listener); RongIMClient.setOnRecallMessageListener(listenerBack); Constants.nowId = ""; @@ -298,35 +293,6 @@ public class MyTUIConversationFragment extends Fragment { }); } - //获取新信息 - OnReceiveMessageWrapperListener listener = new OnReceiveMessageWrapperListener() { - @Override - public void onReceivedMessage(Message message, ReceivedProfile profile) { - Log.d("刷新消息", "message=" + message); - Log.i("Log", "message=" + message); - if (message.getTargetId() != null && !"".endsWith(message.getTargetId())) { - String firstIndex = message.getTargetId().substring(0, 1); - if (!"g".endsWith(firstIndex) && !"__system__".endsWith(message.getTargetId())) { - String firstIndexRM = ""; - String firstIndexRM2 = ""; - if (message.getObjectName().equals("RC:TxtMsg")) { - TextMessage rongMsg = (TextMessage) message.getContent(); - if (rongMsg.getContent().length() > 4) { - firstIndexRM = rongMsg.getContent().substring(0, 5); - } - if (rongMsg.getContent().length() > 9) { - firstIndexRM2 = rongMsg.getContent().substring(0, 10); - } - } - if (!"{\"msg".equals(firstIndexRM) && !"{\"retcode\"".equals(firstIndexRM2)) { - //切换回主线程做UI操作 - mHandler.sendEmptyMessage(runOnUI); - messageHandler = message; - } - } - } - } - }; //撤回消息 RongIMClient.OnRecallMessageListener listenerBack = new RongIMClient.OnRecallMessageListener() { diff --git a/live/src/main/java/com/yunbao/live/activity/PDLIiveChatActivity.java b/live/src/main/java/com/yunbao/live/activity/PDLIiveChatActivity.java new file mode 100644 index 000000000..18e07bc0f --- /dev/null +++ b/live/src/main/java/com/yunbao/live/activity/PDLIiveChatActivity.java @@ -0,0 +1,63 @@ +package com.yunbao.live.activity; + +import android.os.Bundle; +import android.view.Gravity; +import android.view.Window; +import android.view.WindowManager; + +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; + +import com.yunbao.common.activity.AbsActivity; +import com.yunbao.live.R; + +import io.rong.imkit.conversationlist.ConversationListFragment; + +/** + * 直播页面聊天列表 + */ +public class PDLIiveChatActivity extends AbsActivity { + @Override + protected int getLayoutId() { + return R.layout.activity_pd_chat; + + } + + @Override + protected void main(Bundle savedInstanceState) { + super.main(savedInstanceState); + windowColor(); + initView(); + } + + public void windowColor() { + Window window = getWindow(); + //取消设置Window半透明的Flag + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + //添加Flag把状态栏设为可绘制模式 + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + //设置状态栏为透明/或者需要的颜色 + window.setStatusBarColor(getResources().getColor(R.color.transparent)); + + getWindow().setGravity(Gravity.BOTTOM);//设置显示在底部 默认在中间 + WindowManager.LayoutParams lp = getWindow().getAttributes(); + lp.width = WindowManager.LayoutParams.MATCH_PARENT;//设置宽度满屏 + lp.height = WindowManager.LayoutParams.WRAP_CONTENT; + getWindow().setAttributes(lp); + setFinishOnTouchOutside(true);//允许点击空白处关闭 + + } + /** + * 初始化控件 + */ + private void initView() { + //展示会话列表 + ConversationListFragment conversationListFragment = new ConversationListFragment(); + FragmentManager manager = getSupportFragmentManager(); + FragmentTransaction transaction = manager.beginTransaction(); + transaction.replace(R.id.container, conversationListFragment); + transaction.commit(); + //自定义空数据背景View + conversationListFragment.setEmptyView(com.yunbao.live.R.layout.view_layout_msg); + } +} diff --git a/live/src/main/java/com/yunbao/live/activity/PDLiveConversationActivity.java b/live/src/main/java/com/yunbao/live/activity/PDLiveConversationActivity.java new file mode 100644 index 000000000..78d880f34 --- /dev/null +++ b/live/src/main/java/com/yunbao/live/activity/PDLiveConversationActivity.java @@ -0,0 +1,183 @@ +package com.yunbao.live.activity; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; + +import com.blankj.utilcode.util.GsonUtils; +import com.yunbao.common.activity.AbsActivity; +import com.yunbao.common.activity.SelectImageActivity; +import com.yunbao.common.bean.IMLoginModel; +import com.yunbao.common.bean.ImageEntity; +import com.yunbao.common.manager.IMLoginManager; +import com.yunbao.live.R; +import com.yunbao.live.bean.SearchUserBean; +import com.yunbao.live.dialog.MenuPopuwWindow; +import com.yunbao.live.views.InputPanelViewHolder; + +import java.util.ArrayList; + +import io.rong.imkit.conversation.ConversationFragment; +import io.rong.imkit.userinfo.RongUserInfoManager; +import io.rong.imlib.model.UserInfo; + +/** + * 聊天会话界面 + */ +public class PDLiveConversationActivity extends AbsActivity implements View.OnClickListener { + private ConversationFragment conversationFragment; + private PDLiveConversationActivity mContext; + private InputPanelViewHolder inputPanel; + private TextView titleView; + private ImageView imgMore, imBack; + private boolean isAdmin = false; + private final int PERMISSION_REQUEST_CODE = 0; + private final int SELECT_VIDEO_REQUEST = 0x0002; + private final int SELECT_IMAGE_REQUEST = 0x0001; + private ArrayList mSelectImages = new ArrayList<>(); + private String targetId = ""; + + + @Override + protected int getLayoutId() { + return R.layout.activity_conversation; + } + + @Override + protected void main() { + super.main(); + mContext = this; + getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); + initView(); + initData(); + } + + /** + * 数据的设置 + */ + private void initData() { + targetId = getIntent().getStringExtra("targetId"); + //绑定聊天用户id + inputPanel.setTargetId(targetId); + //获取用户信息 + UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(targetId); + titleView.setText(userInfo.getName()); + if (!TextUtils.isEmpty(userInfo.getExtra())) { + SearchUserBean userBean = GsonUtils.fromJson(userInfo.getExtra(), SearchUserBean.class); + //新手指导员 + if (TextUtils.isEmpty(userBean.getIs_admin()) && TextUtils.equals(userBean.getIs_admin(), "1")) { + isAdmin = true; + } else {//非指导员 + isAdmin = false; + } + Log.e("PDLiveConversation", userInfo.getExtra()); + } + + } + + /** + * 初始化布局 + */ + private void initView() { + // 添加会话界面 + conversationFragment = new ConversationFragment(); + FragmentManager manager = getSupportFragmentManager(); + FragmentTransaction transaction = manager.beginTransaction(); + transaction.replace(R.id.container, conversationFragment); + transaction.commit(); + inputPanel = findViewById(R.id.input_panel); + titleView = findViewById(R.id.titleView); + imgMore = findViewById(R.id.img_more); + imBack = findViewById(R.id.btn_back); + imgMore.setOnClickListener(this); + imBack.setOnClickListener(this); + findViewById(R.id.container).setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + InputMethodManager imm = (InputMethodManager) + getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(v.getWindowToken(), 0); + return false; + } + }); + inputPanel.addMediaMessageCallback(new InputPanelViewHolder.MediaMessageCallback() { + @Override + public void choosePic(int intoIndex) { + jumpPic(intoIndex); + } + }); + + } + + + @Override + public void onClick(View v) { + int id = v.getId(); + //菜单 + if (id == R.id.img_more) { + IMLoginModel model = IMLoginManager.get(mContext).getUserInfo(); + new MenuPopuwWindow(mContext).setIsAdmin(model.getIsAdmin(), targetId).show(imgMore); + } else if (id == R.id.btn_back) {//返回 + onBackPressed(); + } + } + + //intoIndex 1=调用相机,2=照片选取,3=视频选取 + public void jumpPic(int intoIndex) { + //选择图片 + int isPermission1 = ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE); + int isPermission2 = ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE); + if (isPermission1 == PackageManager.PERMISSION_GRANTED && isPermission2 == PackageManager.PERMISSION_GRANTED) { + startActivity(intoIndex); + } else { + //申请权限 + ActivityCompat.requestPermissions(mContext, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE); + } + } + + private void startActivity(int intoIndex) { + mSelectImages.clear(); + Intent intent = new Intent(mContext, SelectImageActivity.class); + intent.putParcelableArrayListExtra("selected_images", mSelectImages); + intent.putExtra("intoIndex", intoIndex); + if (intoIndex == 3) { + startActivityForResult(intent, SELECT_VIDEO_REQUEST); + } else { + startActivityForResult(intent, SELECT_IMAGE_REQUEST); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == SELECT_IMAGE_REQUEST && data != null) { + ArrayList selectImages = data.getParcelableArrayListExtra(SelectImageActivity.EXTRA_RESULT); + for (ImageEntity entity : selectImages) { + inputPanel.sendImageFile(entity.getPath()); + } + + } else if (requestCode == SELECT_VIDEO_REQUEST && data != null) { + ArrayList selectImages = data.getParcelableArrayListExtra(SelectImageActivity.EXTRA_RESULT); + for (ImageEntity entity : selectImages) { + inputPanel.sendVideoFile(entity.getPath()); + } + } + } + } +} diff --git a/live/src/main/java/com/yunbao/live/activity/SystemMessageActivity.java b/live/src/main/java/com/yunbao/live/activity/SystemMessageActivity.java index cf852417f..0d3b5ab39 100644 --- a/live/src/main/java/com/yunbao/live/activity/SystemMessageActivity.java +++ b/live/src/main/java/com/yunbao/live/activity/SystemMessageActivity.java @@ -16,13 +16,9 @@ import com.yunbao.live.views.SystemMessageViewHolder; import java.util.ArrayList; import java.util.Date; -import io.rong.imlib.RongCoreClient; import io.rong.imlib.RongIMClient; -import io.rong.imlib.listener.OnReceiveMessageWrapperListener; import io.rong.imlib.model.Conversation; import io.rong.imlib.model.Message; -import io.rong.imlib.model.ReceivedProfile; -import io.rong.message.TextMessage; /** * Created by cxf on 2018/11/24. @@ -58,7 +54,6 @@ public class SystemMessageActivity extends AbsActivity { if ("-2".equals(type)) { type = "-1"; type2 = "-2"; - RongCoreClient.addOnReceiveMessageListener(listener); } else { type2 = "0"; } @@ -110,7 +105,6 @@ public class SystemMessageActivity extends AbsActivity { Constants.remarks = ""; Constants.isAdmin = ""; if ("-2".equals(type2)) { - RongCoreClient.removeOnReceiveMessageListener(listener); } super.onDestroy(); } @@ -142,40 +136,6 @@ public class SystemMessageActivity extends AbsActivity { } } - //获取新信息 - private OnReceiveMessageWrapperListener listener = new OnReceiveMessageWrapperListener() { - @Override - public void onReceivedMessage(Message message, ReceivedProfile profile) { - Log.i("Log", "message=" + message); - if (message.getTargetId() != null && !"".endsWith(message.getTargetId())) { - String firstIndex = message.getTargetId().substring(0, 1); - if (!"g".endsWith(firstIndex) && !"__system__".endsWith(message.getTargetId())) { - String firstIndexRM = ""; - String firstIndexRM2 = ""; - if (message.getObjectName().equals("RC:TxtMsg")) { - TextMessage rongMsg = (TextMessage) message.getContent(); - if (rongMsg.getContent().length() > 4) { - firstIndexRM = rongMsg.getContent().substring(0, 5); - } - if (rongMsg.getContent().length() > 9) { - firstIndexRM2 = rongMsg.getContent().substring(0, 10); - } - } - if (!"{\"msg".equals(firstIndexRM) && !"{\"retcode\"".equals(firstIndexRM2)) { - if (message.getObjectName().equals("RC:TxtMsg")) { - getNewMsg(message); - } else if (message.getObjectName().equals("RC:ImgMsg")) { - getNewMsg(message); - } else if (message.getObjectName().equals("RC:SightMsg")) { - getNewMsg(message); - } - cleanMessage(message.getTargetId()); - } - } - } - } - }; - //清除指定会话未读数 private void cleanMessage(String toId) { diff --git a/live/src/main/java/com/yunbao/live/adapter/SystemMessageAdapter.java b/live/src/main/java/com/yunbao/live/adapter/SystemMessageAdapter.java index 151a6c0d7..bf6195f8e 100644 --- a/live/src/main/java/com/yunbao/live/adapter/SystemMessageAdapter.java +++ b/live/src/main/java/com/yunbao/live/adapter/SystemMessageAdapter.java @@ -90,4 +90,5 @@ public class SystemMessageAdapter extends RefreshAdapter { } } } + } diff --git a/live/src/main/java/com/yunbao/live/bean/ImUserBean.java b/live/src/main/java/com/yunbao/live/bean/ImUserBean.java index bc15ccab6..7b5e56890 100644 --- a/live/src/main/java/com/yunbao/live/bean/ImUserBean.java +++ b/live/src/main/java/com/yunbao/live/bean/ImUserBean.java @@ -2,10 +2,14 @@ package com.yunbao.live.bean; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; import com.alibaba.fastjson.annotation.JSONField; import com.yunbao.common.bean.UserBean; +import java.text.SimpleDateFormat; +import java.util.Date; + /** * Created by cxf on 2017/8/14. * IM 聊天用户 实体类 @@ -112,4 +116,23 @@ public class ImUserBean { public void setUserId(String userId) { this.userId = userId; } + + /** + * 会话列表展示时间 + */ + public String getLastDate() { + if (!TextUtils.isEmpty(addtime)&&!TextUtils.equals(addtime,"0")) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + Date currenTimeZone; + if (TextUtils.equals(type, "-1")) { + currenTimeZone = new Date(Long.parseLong(addtime)); + } else { + currenTimeZone = new Date(Long.parseLong(addtime + "000")); + } + return sdf.format(currenTimeZone); + } else { + return ""; + } + + } } diff --git a/live/src/main/java/com/yunbao/live/dialog/LiveChatListDialogFragment.java b/live/src/main/java/com/yunbao/live/dialog/LiveChatListDialogFragment.java index 4812d1ba9..cd659a7e3 100644 --- a/live/src/main/java/com/yunbao/live/dialog/LiveChatListDialogFragment.java +++ b/live/src/main/java/com/yunbao/live/dialog/LiveChatListDialogFragment.java @@ -3,14 +3,8 @@ package com.yunbao.live.dialog; import android.content.DialogInterface; import android.content.Intent; import android.graphics.drawable.BitmapDrawable; -import android.media.Ringtone; -import android.media.RingtoneManager; -import android.net.Uri; import android.os.Bundle; import android.os.Handler; -import androidx.cardview.widget.CardView; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import android.text.TextUtils; import android.util.Log; import android.view.Gravity; @@ -24,6 +18,10 @@ import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.TextView; +import androidx.cardview.widget.CardView; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; @@ -56,12 +54,9 @@ import java.util.Collections; import java.util.Date; import java.util.List; -import io.rong.imlib.RongCoreClient; import io.rong.imlib.RongIMClient; -import io.rong.imlib.listener.OnReceiveMessageWrapperListener; import io.rong.imlib.model.Conversation; import io.rong.imlib.model.Message; -import io.rong.imlib.model.ReceivedProfile; import io.rong.message.RecallNotificationMessage; import io.rong.message.TextMessage; @@ -162,7 +157,6 @@ public class LiveChatListDialogFragment extends AbsDialogFragment { ImHttpUtil.cancel(ImHttpConsts.GET_SYSTEM_MESSAGE_LIST); ImHttpUtil.cancel(ImHttpConsts.GET_IM_USER_INFO); Constants.isShowLiveDialog = false; - RongCoreClient.removeOnReceiveMessageListener(listener); } private void initView() { @@ -209,7 +203,6 @@ public class LiveChatListDialogFragment extends AbsDialogFragment { }); mRecyclerView.setAdapter(mAdapter); - RongCoreClient.addOnReceiveMessageListener(listener); RongIMClient.setOnRecallMessageListener(listenerBack); Constants.nowId = ""; @@ -299,59 +292,6 @@ public class LiveChatListDialogFragment extends AbsDialogFragment { }); } - //获取新信息 - OnReceiveMessageWrapperListener listener = new OnReceiveMessageWrapperListener() { - @Override - public void onReceivedMessage(Message message, ReceivedProfile profile) { - Log.i("Log", "message=" + message); - if (message.getTargetId() != null && !"".endsWith(message.getTargetId())) { - String firstIndex = message.getTargetId().substring(0, 1); - if (!"g".endsWith(firstIndex) && !"__system__".endsWith(message.getTargetId())) { - String firstIndexRM = ""; - String firstIndexRM2 = ""; - if (message.getObjectName().equals("RC:TxtMsg")) { - TextMessage rongMsg = (TextMessage) message.getContent(); - if (rongMsg.getContent().length() > 4) { - firstIndexRM = rongMsg.getContent().substring(0, 5); - } - if (rongMsg.getContent().length() > 9) { - firstIndexRM2 = rongMsg.getContent().substring(0, 10); - } - } - if (!"{\"msg".equals(firstIndexRM) && !"{\"retcode\"".equals(firstIndexRM2)) { - if (lt_nodata_msg.getVisibility() == View.VISIBLE) { - lt_nodata_msg.setVisibility(View.GONE); - } - if (systemMessageActivity != null && !Constants.nowId.equals("")) { - if (Constants.isShowLiveDialog) {//直播间单聊插入消息 - if (message.getObjectName().equals("RC:TxtMsg")) { - systemMessageActivity.getNewMsg(message); - } else if (message.getObjectName().equals("RC:ImgMsg")) { - systemMessageActivity.getNewMsg(message); - } else if (message.getObjectName().equals("RC:SightMsg")) { - systemMessageActivity.getNewMsg(message); - } - cleanMessage(null, message.getTargetId()); - } - } else { - if (systemMessageActivity.nowUid != null && !message.getTargetId().equals(systemMessageActivity.nowUid)) { - //新信息提示 - try { - Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); - Ringtone r = RingtoneManager.getRingtone(getActivity(), notification); - r.play(); - } catch (Exception e) { - e.getMessage(); - } - } - getChatPoint(); - getOneUserChat(message.getTargetId()); - } - } - } - } - } - }; //撤回消息 RongIMClient.OnRecallMessageListener listenerBack = new RongIMClient.OnRecallMessageListener() { diff --git a/live/src/main/java/com/yunbao/live/dialog/MenuPopuwWindow.java b/live/src/main/java/com/yunbao/live/dialog/MenuPopuwWindow.java new file mode 100644 index 000000000..5d85b921a --- /dev/null +++ b/live/src/main/java/com/yunbao/live/dialog/MenuPopuwWindow.java @@ -0,0 +1,138 @@ +package com.yunbao.live.dialog; + +import android.app.Activity; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.TextView; + +import com.yunbao.common.utils.ToastUtil; +import com.yunbao.live.R; + +import io.rong.imlib.RongIMClient; + +/** + * 聊天菜单弹窗 + */ +public class MenuPopuwWindow implements View.OnClickListener { + private Activity mContext; + private String userId; + private View popupView; + private TextView tvBlack, tvBlackMove; + private LinearLayout ltRemarks; + private PopupWindow popupWindow; + + public MenuPopuwWindow(Activity context) { + this.mContext = context; + popupView = LayoutInflater.from(mContext).inflate(R.layout.popwindow_chat_more, null); + initView(); + } + + public MenuPopuwWindow setIsAdmin(String isAdmin, String userId) { + this.userId = userId; + + if (TextUtils.equals(isAdmin, "1")) { + tvBlack.setVisibility(View.GONE); + tvBlackMove.setVisibility(View.GONE); + ltRemarks.setVisibility(View.VISIBLE); + } else { + ltRemarks.setVisibility(View.GONE); + RongIMClient.getInstance().getBlacklistStatus(userId, new RongIMClient.ResultCallback() { + @Override + public void onSuccess(RongIMClient.BlacklistStatus blacklistStatus) { + if (blacklistStatus == RongIMClient.BlacklistStatus.IN_BLACK_LIST) { + tvBlackMove.setVisibility(View.VISIBLE); + tvBlack.setVisibility(View.GONE); + } else { + tvBlack.setVisibility(View.VISIBLE); + tvBlackMove.setVisibility(View.GONE); + } + } + + @Override + public void onError(RongIMClient.ErrorCode errorCode) { + + } + }); + } + return this; + } + + /** + * 初始化组件 + */ + private void initView() { + tvBlack = popupView.findViewById(R.id.tv_black); + tvBlackMove = popupView.findViewById(R.id.tv_black_move); + ltRemarks = popupView.findViewById(R.id.lt_remarks); + tvBlack.setOnClickListener(this); + tvBlackMove.setOnClickListener(this); + ltRemarks.setOnClickListener(this); + } + + /** + * 展示弹窗 + * + * @param view 显示在什么组件的下面 + * @return + */ + public void show(View view) { + popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); + popupWindow.showAsDropDown(view); + WindowManager.LayoutParams lp = mContext.getWindow().getAttributes(); + lp.alpha = 0.8f; + mContext.getWindow().setAttributes(lp); + popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { + @Override + public void onDismiss() { + lp.alpha = 1f; + mContext.getWindow().setAttributes(lp); + } + }); + } + + @Override + public void onClick(View v) { + int id = v.getId(); + //拉黑 + if (id == R.id.tv_black) { + RongIMClient.getInstance().addToBlacklist(userId, new RongIMClient.OperationCallback() { + @Override + public void onSuccess() { + ToastUtil.show(mContext.getResources().getString(R.string.black_succer)); + popupWindow.dismiss(); + tvBlack.setVisibility(View.VISIBLE); + tvBlackMove.setVisibility(View.GONE); + } + + @Override + public void onError(RongIMClient.ErrorCode errorCode) { + ToastUtil.show(errorCode.msg); + popupWindow.dismiss(); + } + }); + } else if (id == R.id.tv_black_move) {//移出黑名单 + RongIMClient.getInstance().removeFromBlacklist(userId, new RongIMClient.OperationCallback() { + @Override + public void onSuccess() { + ToastUtil.show(mContext.getResources().getString(R.string.black_succer_more)); + popupWindow.dismiss(); + tvBlackMove.setVisibility(View.VISIBLE); + tvBlack.setVisibility(View.GONE); + } + + @Override + public void onError(RongIMClient.ErrorCode errorCode) { + ToastUtil.show(errorCode.msg); + popupWindow.dismiss(); + } + }); + } else if (id == R.id.lt_remarks) {//添加备注 + + } + } +} diff --git a/live/src/main/java/com/yunbao/live/utils/FileSizeUtil.java b/live/src/main/java/com/yunbao/live/utils/FileSizeUtil.java new file mode 100644 index 000000000..e09d377b6 --- /dev/null +++ b/live/src/main/java/com/yunbao/live/utils/FileSizeUtil.java @@ -0,0 +1,155 @@ +package com.yunbao.live.utils; + +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.text.DecimalFormat; + + +public class FileSizeUtil { + + public static final int SIZETYPE_B = 1;//获取文件大小单位为B的double值 + public static final int SIZETYPE_KB = 2;//获取文件大小单位为KB的double值 + public static final int SIZETYPE_MB = 3;//获取文件大小单位为MB的double值 + public static final int SIZETYPE_GB = 4;//获取文件大小单位为GB的double值 + + /** + * 获取文件指定文件的指定单位的大小 + * + * @param filePath 文件路径 + * @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB + * @return double值的大小 + */ + public static double getFileOrFilesSize(String filePath, int sizeType) { + File file = new File(filePath); + long blockSize = 0; + try { + if (file.isDirectory()) { + blockSize = getFileSizes(file); + } else { + blockSize = getFileSize(file); + } + } catch (Exception e) { + e.printStackTrace(); + Log.e("获取文件大小", "获取失败!"); + } + return FormetFileSize(blockSize, sizeType); + } + + /** + * 调用此方法自动计算指定文件或指定文件夹的大小 + * + * @param filePath 文件路径 + * @return 计算好的带B、KB、MB、GB的字符串 + */ + public static String getAutoFileOrFilesSize(String filePath) { + File file = new File(filePath); + long blockSize = 0; + try { + if (file.isDirectory()) { + blockSize = getFileSizes(file); + } else { + blockSize = getFileSize(file); + } + } catch (Exception e) { + e.printStackTrace(); + Log.e("获取文件大小", "获取失败!"); + } + return FormetFileSize(blockSize); + } + + /** + * 获取指定文件大小 + * + * @param file + * @return + * @throws Exception + */ + private static long getFileSize(File file) throws Exception { + long size = 0; + if (file.exists()) { + FileInputStream fis = null; + fis = new FileInputStream(file); + size = fis.available(); + } else { + file.createNewFile(); + Log.e("获取文件大小", "文件不存在!"); + } + return size; + } + + /** + * 获取指定文件夹 + * + * @param f + * @return + * @throws Exception + */ + private static long getFileSizes(File f) throws Exception { + long size = 0; + File flist[] = f.listFiles(); + for (int i = 0; i < flist.length; i++) { + if (flist[i].isDirectory()) { + size = size + getFileSizes(flist[i]); + } else { + size = size + getFileSize(flist[i]); + } + } + return size; + } + + /** + * 转换文件大小 + * + * @param fileS + * @return + */ + private static String FormetFileSize(long fileS) { + DecimalFormat df = new DecimalFormat("#.00"); + String fileSizeString = ""; + String wrongSize = "0B"; + if (fileS == 0) { + return wrongSize; + } + if (fileS < 1024) { + fileSizeString = df.format((double) fileS) + "B"; + } else if (fileS < 1048576) { + fileSizeString = df.format((double) fileS / 1024) + "KB"; + } else if (fileS < 1073741824) { + fileSizeString = df.format((double) fileS / 1048576) + "MB"; + } else { + fileSizeString = df.format((double) fileS / 1073741824) + "GB"; + } + return fileSizeString; + } + + /** + * 转换文件大小,指定转换的类型 + * + * @param fileS + * @param sizeType + * @return + */ + private static double FormetFileSize(long fileS, int sizeType) { + DecimalFormat df = new DecimalFormat("#.00"); + double fileSizeLong = 0; + switch (sizeType) { + case SIZETYPE_B: + fileSizeLong = Double.valueOf(df.format((double) fileS)); + break; + case SIZETYPE_KB: + fileSizeLong = Double.valueOf(df.format((double) fileS / 1024)); + break; + case SIZETYPE_MB: + fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576)); + break; + case SIZETYPE_GB: + fileSizeLong = Double.valueOf(df.format((double) fileS / 1073741824)); + break; + default: + break; + } + return fileSizeLong; + } +} diff --git a/live/src/main/java/com/yunbao/live/views/InputPanelViewHolder.java b/live/src/main/java/com/yunbao/live/views/InputPanelViewHolder.java new file mode 100644 index 000000000..16668a925 --- /dev/null +++ b/live/src/main/java/com/yunbao/live/views/InputPanelViewHolder.java @@ -0,0 +1,293 @@ +package com.yunbao.live.views; + +import android.content.Context; +import android.net.Uri; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +import com.yunbao.common.utils.ToastUtil; +import com.yunbao.live.R; +import com.yunbao.live.utils.FileSizeUtil; + +import io.rong.imkit.IMCenter; +import io.rong.imlib.IRongCallback; +import io.rong.imlib.RongIMClient; +import io.rong.imlib.model.Conversation; +import io.rong.imlib.model.Message; +import io.rong.message.FileMessage; +import io.rong.message.ImageMessage; +import io.rong.message.TextMessage; + +/** + * 自定义输入区 + */ +public class InputPanelViewHolder extends LinearLayout implements View.OnClickListener { + private ImageView inputPanelAddBtn; + private EditText editBtn; + public Button inputPanelSendBtn; + //接收方的用户id + private String targetId; + //是否可以发送消息 + private boolean isSend = false; + private LinearLayout pluginList; + + + /** + * 必传字段 + * + * @param targetId 接收方的用户id + * @return + */ + public InputPanelViewHolder setTargetId(String targetId) { + this.targetId = targetId; + return this; + } + + public InputPanelViewHolder(Context context) { + super(context); + } + + public InputPanelViewHolder(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + View inputPanelView = View.inflate(context, R.layout.view_input_panel, this); + initView(inputPanelView); + } + + /** + * 初始化布局 + */ + private void initView(View inputPanelView) { + inputPanelAddBtn = inputPanelView.findViewById(R.id.input_panel_add_btn); + editBtn = inputPanelView.findViewById(R.id.edit_btn); + inputPanelSendBtn = inputPanelView.findViewById(R.id.input_panel_send_btn); + pluginList = inputPanelView.findViewById(R.id.plugin_list); + editBtn.addTextChangedListener(mEditTextWatcher); + inputPanelSendBtn.setOnClickListener(this); + inputPanelAddBtn.setOnClickListener(this); + editBtn.setOnClickListener(this); + inputPanelView.findViewById(R.id.lt_photo_button).setOnClickListener(this); + inputPanelView.findViewById(R.id.lt_choospic_button).setOnClickListener(this); + inputPanelView.findViewById(R.id.lt_video_button).setOnClickListener(this); + + + } + + @Override + public void onClick(View v) { + int id = v.getId(); + //点击加号拓展按钮 + if (id == R.id.input_panel_add_btn) { + showPlugin(); + //点击发送按钮 + } else if (id == R.id.input_panel_send_btn) { + sendMessage(); + } else if (id == R.id.edit_btn) { + if (pluginList.getVisibility() == VISIBLE) { + pluginList.setVisibility(GONE); + } + } else if (id == R.id.lt_photo_button) { + if (messageCallback != null) { + messageCallback.choosePic(1); + } + } else if (id == R.id.lt_choospic_button) { + if (messageCallback != null) { + messageCallback.choosePic(2); + } + } else if (id == R.id.lt_video_button) { + if (messageCallback != null) { + messageCallback.choosePic(3); + } + } + } + + /** + * 展示拓展插件列表 + */ + private void showPlugin() { + if (pluginList.getVisibility() == VISIBLE) { + pluginList.setVisibility(GONE); + } else { + InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(editBtn, InputMethodManager.SHOW_FORCED); + + imm.hideSoftInputFromWindow(editBtn.getWindowToken(), 0); //强制隐藏键盘 + pluginList.setVisibility(VISIBLE); + } + + } + + /** + * 发送文字消息 + */ + private void sendMessage() { + if (!isSend) return; + if (!TextUtils.isEmpty(editBtn.getText()) && !TextUtils.isEmpty(editBtn.getText().toString().trim())) { + String text = editBtn.getText().toString(); + editBtn.setText(""); + Conversation.ConversationType conversationType = Conversation.ConversationType.PRIVATE; + TextMessage messageContent = TextMessage.obtain(text); + Message message = Message.obtain(targetId, conversationType, messageContent); + IMCenter.getInstance().sendMessage(message, null, null, new IRongCallback.ISendMessageCallback() { + + @Override + public void onAttached(Message message) { + + } + + @Override + public void onSuccess(Message message) { + + } + + @Override + public void onError(Message message, RongIMClient.ErrorCode errorCode) { + + } + }); + } else { + ToastUtil.show("不可以发送空消息"); + } + + } + + private TextWatcher mEditTextWatcher = new TextWatcher() { + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + public void onTextChanged(CharSequence s, int start, int before, int count) { + //存入草稿 + Conversation.ConversationType types = Conversation.ConversationType.PRIVATE; + if (s != null && s.length() != 0) { + isSend = true; + inputPanelSendBtn.setBackground(getResources().getDrawable(R.mipmap.btn_sand1)); + } else { + isSend = false; + IMCenter.getInstance().saveTextMessageDraft(types, targetId, editBtn.getText().toString(), null); + inputPanelSendBtn.setBackground(getResources().getDrawable(R.mipmap.btn_sand)); + } + int offset; + if (count == 0) { + int var10000 = start + before; + offset = -before; + } else { + offset = count; + } + if (offset != 0) { + RongIMClient.getInstance().sendTypingStatus(types, targetId, "RC:TxtMsg"); + } + } + + public void afterTextChanged(Editable s) { + } + }; + + /** + * 发送媒体消息 + * + * @param imagePath + */ + public void sendImageFile(String imagePath) { + if (pluginList.getVisibility() == VISIBLE) { + pluginList.setVisibility(GONE); + } + Uri localUri = Uri.parse("file://" + imagePath); + ImageMessage imageMessage = ImageMessage.obtain(localUri, localUri); + Conversation.ConversationType conversationType = Conversation.ConversationType.PRIVATE; + Message message = Message.obtain(targetId, conversationType, imageMessage); + + IMCenter.getInstance().sendMediaMessage(message, null, null, new IRongCallback.ISendMediaMessageCallback() { + @Override + public void onProgress(Message message, int i) { + + } + + @Override + public void onCanceled(Message message) { + + } + + @Override + public void onAttached(Message message) { + + } + + @Override + public void onSuccess(Message message) { + + } + + @Override + public void onError(final Message message, final RongIMClient.ErrorCode errorCode) { + + } + }); + } + + public void sendVideoFile(String filePath) { + if (pluginList.getVisibility() == VISIBLE) { + pluginList.setVisibility(GONE); + } + Message message; + double fileSize = FileSizeUtil.getFileOrFilesSize(filePath, FileSizeUtil.SIZETYPE_MB); + Uri localUri = Uri.parse("file://" + filePath); + Conversation.ConversationType conversationType = Conversation.ConversationType.PRIVATE; + + + FileMessage videoMessage = FileMessage.obtain(getContext(), localUri); + + message = Message.obtain(targetId, conversationType, videoMessage); + + IMCenter.getInstance().sendMediaMessage(message, null, null, new IRongCallback.ISendMediaMessageCallback() { + @Override + public void onProgress(Message message, int i) { + + } + + @Override + public void onCanceled(Message message) { + + } + + @Override + public void onAttached(Message message) { + + } + + @Override + public void onSuccess(Message message) { + + } + + @Override + public void onError(final Message message, final RongIMClient.ErrorCode errorCode) { + ToastUtil.show(errorCode.msg); + } + }); + + } + + + /** + * 多媒体信息 + */ + public interface MediaMessageCallback { + void choosePic(int intoIndex); + } + + private MediaMessageCallback messageCallback; + + public void addMediaMessageCallback(MediaMessageCallback callback) { + messageCallback = callback; + } + +} diff --git a/live/src/main/java/com/yunbao/live/views/LiveAudienceViewHolder.java b/live/src/main/java/com/yunbao/live/views/LiveAudienceViewHolder.java index e56f987ec..d236ed887 100644 --- a/live/src/main/java/com/yunbao/live/views/LiveAudienceViewHolder.java +++ b/live/src/main/java/com/yunbao/live/views/LiveAudienceViewHolder.java @@ -6,7 +6,6 @@ import android.content.Context; import android.os.Bundle; import android.os.CountDownTimer; import android.os.Handler; -import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -14,35 +13,27 @@ import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.yunbao.common.CommonAppConfig; import com.yunbao.common.Constants; import com.yunbao.common.event.UpdateTablePoint; import com.yunbao.common.http.HttpCallback; import com.yunbao.common.http.HttpClient; +import com.yunbao.common.manager.imrongcloud.MessageIMManager; import com.yunbao.common.utils.ToastUtil; import com.yunbao.live.R; import com.yunbao.live.activity.LiveActivity; import com.yunbao.live.activity.LiveAudienceActivity; -import com.yunbao.live.bean.ImUserBean; import com.yunbao.live.bean.LiveChatBean; import com.yunbao.live.dialog.LiveHDDialogFragment; import com.yunbao.live.dialog.LiveMicUserDialogFragment; import com.yunbao.live.dialog.LivePromotionDialogFragment; -import com.yunbao.live.http.ImHttpUtil; import com.yunbao.live.http.LiveHttpUtil; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; -import java.util.Arrays; -import java.util.List; - -import io.rong.imlib.RongIMClient; -import io.rong.imlib.model.Conversation; - /** * Created by cxf on 2018/10/9. * 观众直播间逻辑 @@ -118,7 +109,7 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder { v_msg_redpoint = (View) findViewById(R.id.v_msg_redpoint); //获取系统未读消息 - getSystemMessages(); + MessageIMManager.get(context).getSystemMessages(); EventBus.getDefault().register(LiveAudienceViewHolder.this); } @@ -363,73 +354,6 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder { public void timeOver() { } - public void getChatPoint() { - if (v_msg_redpoint.getVisibility() == View.GONE) { - Conversation.ConversationType[] conversationTypes = {Conversation.ConversationType.PRIVATE, Conversation.ConversationType.GROUP}; - boolean containBlocked = true; - RongIMClient.getInstance().getUnreadCount(conversationTypes, containBlocked, - new RongIMClient.ResultCallback() { - - @Override - public void onSuccess(Integer unReadCount) { - //未读消息大于0更改红点状态 - if (unReadCount > 0) - changeMessagePoint(unReadCount); - } - - @Override - public void onError(RongIMClient.ErrorCode ErrorCode) { - changeMessagePoint(0); - } - }); - } - - } - - /** - * 获取系统消息(有未读数展示红点) - */ - private void getSystemMessages() { - //获取系统消息列表 - ImHttpUtil.getImUserInfo("", new HttpCallback() { - @Override - public void onSuccess(int code, String msg, String[] info) { - if (code == 0) { - //获取系统消息列表 - List listUserBean = JSON.parseArray(Arrays.toString(info), ImUserBean.class); - if (listUserBean != null && listUserBean.size() >= 2) { - //目前就三条消息,需求判断前两条消息是否有未读消息 - for (int i = 0; i < listUserBean.size() - 2; i++) { - //消息对象 - ImUserBean userBean = listUserBean.get(i); - //未读消息数 - String number = userBean.getNum(); - //未读消息不为空并且大于0 - if (!TextUtils.isEmpty(number) && Integer.parseInt(number) > 0) { - context.runOnUiThread(() -> changeMessagePoint(Integer.parseInt(number))); - } - } - } - } - } - }); - } - - /** - * 更改消息红点的状态 - * - * @param number 未读消息 - */ - private void changeMessagePoint(int number) { - //发送通知更改,菜单红点 - EventBus.getDefault().post(new UpdateTablePoint(number)); - if (v_msg_redpoint.getVisibility() == View.VISIBLE && number > 0) return; - if (number > 0) { - v_msg_redpoint.setVisibility(View.VISIBLE); - } else { - v_msg_redpoint.setVisibility(View.GONE); - } - } //红点(直播页面) @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/live/src/main/java/com/yunbao/live/views/SystemMessageViewHolder.java b/live/src/main/java/com/yunbao/live/views/SystemMessageViewHolder.java index 7c72c449a..b9b1cc135 100644 --- a/live/src/main/java/com/yunbao/live/views/SystemMessageViewHolder.java +++ b/live/src/main/java/com/yunbao/live/views/SystemMessageViewHolder.java @@ -778,7 +778,6 @@ public class SystemMessageViewHolder extends AbsViewHolder implements View.OnCli lt_remarks.setVisibility(View.GONE); } PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); -// popupWindow.showAsDropDown(view, view.getWidth(), -view.getHeight()); popupWindow.showAsDropDown(view); WindowManager.LayoutParams lp = nowActivity.getWindow().getAttributes(); lp.alpha = 0.8f; diff --git a/live/src/main/res/layout/activity_conversation.xml b/live/src/main/res/layout/activity_conversation.xml new file mode 100644 index 000000000..9a246fbc1 --- /dev/null +++ b/live/src/main/res/layout/activity_conversation.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/live/src/main/res/layout/activity_pd_chat.xml b/live/src/main/res/layout/activity_pd_chat.xml new file mode 100644 index 000000000..486208db1 --- /dev/null +++ b/live/src/main/res/layout/activity_pd_chat.xml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/live/src/main/res/layout/activity_webview_medal.xml b/live/src/main/res/layout/activity_webview_medal.xml index ee18fca37..cb2b30ea9 100644 --- a/live/src/main/res/layout/activity_webview_medal.xml +++ b/live/src/main/res/layout/activity_webview_medal.xml @@ -1,22 +1,19 @@ + android:id="@+id/rootView" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + android:paddingTop="24dp"> + android:layout_height="match_parent"> + android:textStyle="bold" /> + android:tint="@color/textColor" /> + + android:tint="@color/textColor" /> + + android:progressDrawable="@drawable/bg_horizontal_progressbar" /> \ No newline at end of file diff --git a/live/src/main/res/layout/dialog_live_empty.xml b/live/src/main/res/layout/dialog_live_empty.xml index 6fabd8223..3725404a5 100644 --- a/live/src/main/res/layout/dialog_live_empty.xml +++ b/live/src/main/res/layout/dialog_live_empty.xml @@ -59,19 +59,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> - - - - + android:layout_height="0dp" + android:layout_weight="1" /> diff --git a/live/src/main/res/layout/view_input_panel.xml b/live/src/main/res/layout/view_input_panel.xml new file mode 100644 index 000000000..39edf6596 --- /dev/null +++ b/live/src/main/res/layout/view_input_panel.xml @@ -0,0 +1,144 @@ + + + + + + + + + + + +