Commit 1a98f9aa authored by sheteng's avatar sheteng

未读消息显示

parent 21709ae7
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\she\.android\avd\Copy_of_Copy_of_Pixel_3_XL_API_26.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2022-06-30T07:35:17.411815700Z" />
</component>
</project>
\ No newline at end of file
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
<option value="$PROJECT_DIR$/ccim" /> <option value="$PROJECT_DIR$/ccim" />
</set> </set>
</option> </option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
</component> </component>
......
...@@ -5,7 +5,11 @@ ...@@ -5,7 +5,11 @@
<map> <map>
<entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/layout/activity_login.xml" value="0.1612008072653885" /> <entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/layout/activity_login.xml" value="0.1612008072653885" />
<entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/layout/activity_main2.xml" value="0.1612008072653885" /> <entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/layout/activity_main2.xml" value="0.1612008072653885" />
<entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/layout/fragment_message.xml" value="0.291213768115942" />
<entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/layout/msg_row_item.xml" value="0.2617753623188406" /> <entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/layout/msg_row_item.xml" value="0.2617753623188406" />
<entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/layout/text_row_item.xml" value="0.291213768115942" />
<entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/menu/bottom_nav_menu.xml" value="0.32864583333333336" />
<entry key="..\:/ccwangluo/ccim_sdk_android/app/src/main/res/menu/menu_main.xml" value="0.3328125" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_connect.xml" value="0.3170289855072464" /> <entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_connect.xml" value="0.3170289855072464" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_connect_channel.xml" value="0.26403985507246375" /> <entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_connect_channel.xml" value="0.26403985507246375" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_login.xml" value="0.322463768115942" /> <entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_login.xml" value="0.322463768115942" />
......
...@@ -51,9 +51,9 @@ public class MainActivity2 extends AppCompatActivity { ...@@ -51,9 +51,9 @@ public class MainActivity2 extends AppCompatActivity {
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);//添加默认的返回图标 // getSupportActionBar().setDisplayHomeAsUpEnabled(true);//添加默认的返回图标
getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setHomeButtonEnabled(true);
loginViewModel = new ViewModelProvider(this) loginViewModel = new ViewModelProvider(this)
.get(LoginViewModel.class); .get(LoginViewModel.class);
loginViewModel.getContactList();
CCIMClient.getInstance().registerMessageListener(new OnPushMsgListener() { CCIMClient.getInstance().registerMessageListener(new OnPushMsgListener() {
......
...@@ -206,7 +206,8 @@ public class ContactExpandableAdapter extends BaseExpandableListAdapter { ...@@ -206,7 +206,8 @@ public class ContactExpandableAdapter extends BaseExpandableListAdapter {
childrenHolder.contactId.setText("userid: " + dataList.get(childPosition).getContactUserId()); childrenHolder.contactId.setText("userid: " + dataList.get(childPosition).getContactUserId());
childrenHolder.contactName.setText("username: " + dataList.get(childPosition).getContactUserName()); childrenHolder.contactName.setText("username: " + dataList.get(childPosition).getContactUserName());
childrenHolder.netStatus.setText("netStatus: " + dataList.get(childPosition).getNetStatus().toString()); childrenHolder.netStatus.setText("netStatus: " + dataList.get(childPosition).getNetStatus().toString());
// childrenHolder.status.setText("status: " + dataList.get(childPosition).getStatus()); // childrenHolder.status.setText("status: " + dataList.get(childPosition).);
// childrenHolder.unReadMsg.setText("unReadMsg : " + dataList.get(childPosition).().toString());
convertView.setOnLongClickListener(new View.OnLongClickListener() { convertView.setOnLongClickListener(new View.OnLongClickListener() {
@Override @Override
public boolean onLongClick(View v) { public boolean onLongClick(View v) {
...@@ -384,6 +385,7 @@ public class ContactExpandableAdapter extends BaseExpandableListAdapter { ...@@ -384,6 +385,7 @@ public class ContactExpandableAdapter extends BaseExpandableListAdapter {
contact.setContactUserId(dialog.getContactUserId()); contact.setContactUserId(dialog.getContactUserId());
contact.setNetStatus(dialog.getNetStatus()); contact.setNetStatus(dialog.getNetStatus());
contact.setContactUserName(dialog.getContactUserName()); contact.setContactUserName(dialog.getContactUserName());
contacts.add(contact); contacts.add(contact);
} }
this.dataEntity.add(dialogGroup); this.dataEntity.add(dialogGroup);
......
package com.ccwangluo.im.adapter;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.ccwangluo.ccim.modle.Contact;
import com.ccwangluo.ccim.modle.Dialog;
import com.ccwangluo.im.R;
import com.ccwangluo.im.ui.dashboard.ConnectActivity;
import java.util.List;
public class DialogAdapter extends BaseAdapter {
private List<Dialog> dataList;
private Context context;
public DialogAdapter(List<Dialog> dataList, Context context) {
this.dataList = dataList;
this.context = context;
}
/**
* Provide a reference to the type of views that you are using
* (custom ViewHolder).
*/
public static class ViewHolder {
public TextView contactId;
public TextView contactName;
public TextView netStatus;
public TextView status;
public TextView unReadMsg;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder childrenHolder;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = LayoutInflater.from(context).inflate(R.layout.text_row_item, null);
childrenHolder =new ViewHolder();
childrenHolder.contactId = (TextView) convertView.findViewById(R.id.contactId);
childrenHolder.contactName = (TextView) convertView.findViewById(R.id.contactName);
childrenHolder.netStatus = (TextView) convertView.findViewById(R.id.netStatus);
childrenHolder.status = (TextView) convertView.findViewById(R.id.status);
childrenHolder.unReadMsg = (TextView) convertView.findViewById(R.id.unReadMsg);
convertView.setTag(childrenHolder);
} else {
childrenHolder = (ViewHolder) convertView.getTag();
}
Dialog dialog = dataList.get(position);
childrenHolder.contactId.setText("userid: " + dataList.get(position).getContactUserId());
childrenHolder.contactName.setText("username: " + dataList.get(position).getContactUserName());
childrenHolder.netStatus.setText("netStatus: " + dataList.get(position).getNetStatus().toString());
// childrenHolder.status.setText("status: " + dataList.get(childPosition).);
childrenHolder.unReadMsg.setText("unReadMsg : " + dataList.get(position).getUnReadMsgNum().toString());
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, ConnectActivity.class);
Contact contact = new Contact();
contact.setContactUserId(dialog.getContactUserId());
contact.setNetStatus(dialog.getNetStatus());
contact.setContactUserName(dialog.getContactUserName());
intent.putExtra("contact", contact);
context.startActivity(intent);
dialog.setUnReadMsgNum(0L);
}
});
return convertView;
}
public void refreshData() {
notifyDataSetChanged();
}
}
...@@ -136,6 +136,18 @@ public class ConnectActivity extends AppCompatActivity { ...@@ -136,6 +136,18 @@ public class ConnectActivity extends AppCompatActivity {
} }
privaetMsgAdapter.refreshData(); privaetMsgAdapter.refreshData();
binding.msgList.setSelection(privaetMsgAdapter.getCount() - 1); binding.msgList.setSelection(privaetMsgAdapter.getCount() - 1);
MessageContent messageContent = messageContents.get(messageContents.size() - 1);
CCIMClient.getInstance().updateReadOffset(messageContent.getSenderUserId(), messageContent.getMsgId(), new ResultEventCallback<Void>() {
@Override
public void onSuccess(Void unused) {
}
@Override
public void onFailed(int errorCode) {
}
});
} }
@Override @Override
...@@ -150,6 +162,17 @@ public class ConnectActivity extends AppCompatActivity { ...@@ -150,6 +162,17 @@ public class ConnectActivity extends AppCompatActivity {
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onGetMessage(MessageContent message) { public void onGetMessage(MessageContent message) {
loginViewModel.addPrivateMsg(message); loginViewModel.addPrivateMsg(message);
CCIMClient.getInstance().updateReadOffset(message.getSenderUserId(), message.getMsgId(), new ResultEventCallback<Void>() {
@Override
public void onSuccess(Void unused) {
System.out.println("updateReadOffset success");
}
@Override
public void onFailed(int errorCode) {
System.out.println("updateReadOffset onFailed");
}
});
} }
@Override @Override
......
package com.ccwangluo.im.ui.dashboard;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.ccwangluo.ccim.modle.Contact;
import com.ccwangluo.ccim.modle.Dialog;
import com.ccwangluo.im.R;
import com.ccwangluo.im.adapter.DialogAdapter;
import com.ccwangluo.im.data.LoginViewModel;
import com.ccwangluo.im.databinding.FragmentDashboardBinding;
import com.ccwangluo.im.databinding.FragmentGroupBinding;
import com.ccwangluo.im.databinding.FragmentMessageBinding;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class MessageFragment extends Fragment {
private LoginViewModel loginViewModel;
private FragmentMessageBinding binding;
private List<Dialog> dialogList = new ArrayList<>();
private DialogAdapter dialogAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding= FragmentMessageBinding.inflate(inflater, container, false);
loginViewModel =
new ViewModelProvider(getActivity()).get(LoginViewModel.class);
dialogAdapter = new DialogAdapter(dialogList, getContext());
binding.dialogList.setAdapter(dialogAdapter);
return binding.getRoot();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
loginViewModel.dialogList.observe(getActivity(), new Observer<Collection<Dialog>>() {
@Override
public void onChanged(Collection<Dialog> dialogs) {
dialogList.clear();
dialogList.addAll(dialogs);
dialogAdapter.refreshData();
}
});
}
}
\ No newline at end of file
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:hint="ip" android:hint="ip"
android:text="106.15.237.67" android:text="10.17.4.207"
android:imeActionLabel="@string/action_sign_in_short" android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:selectAllOnFocus="true" android:selectAllOnFocus="true"
......
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.dashboard.MessageFragment">
<ListView
android:id="@+id/dialog_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
\ No newline at end of file
...@@ -45,6 +45,13 @@ ...@@ -45,6 +45,13 @@
android:layout_weight="1" android:layout_weight="1"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/black" /> android:textColor="@color/black" />
<TextView
android:id="@+id/unReadMsg"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="@color/black" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="消息"/>
<item <item
android:id="@+id/navigation_dashboard" android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_home_black_24dp" android:icon="@drawable/ic_home_black_24dp"
android:title="联系人"/> android:title="联系人"/>
<!-- <item-->
<!-- android:id="@+id/navigation_home"-->
<!-- android:icon="@drawable/ic_dashboard_black_24dp"-->
<!-- android:title="我的"/>-->
<item <item
android:id="@+id/navigation_notifications" android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp" android:icon="@drawable/ic_notifications_black_24dp"
......
...@@ -3,18 +3,19 @@ ...@@ -3,18 +3,19 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation" android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_dashboard"> app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="com.ccwangluo.im.ui.dashboard.MessageFragment"
android:label="消息"
tools:layout="@layout/fragment_message" />
<fragment <fragment
android:id="@+id/navigation_dashboard" android:id="@+id/navigation_dashboard"
android:name="com.ccwangluo.im.ui.dashboard.ContactsFragment" android:name="com.ccwangluo.im.ui.dashboard.ContactsFragment"
android:label="联系人" android:label="联系人"
tools:layout="@layout/fragment_dashboard" /> tools:layout="@layout/fragment_dashboard" />
<!-- <fragment-->
<!-- android:id="@+id/navigation_home"-->
<!-- android:name="com.ccwangluo.im.ui.home.GroupFragment"-->
<!-- android:label="群组"-->
<!-- tools:layout="@layout/fragment_group" />-->
<fragment <fragment
......
...@@ -7,7 +7,9 @@ import android.os.Environment; ...@@ -7,7 +7,9 @@ import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.ccwangluo.ccim.listener.OnClientConnectListener; import com.ccwangluo.ccim.listener.OnClientConnectListener;
import com.ccwangluo.ccim.listener.OnConnectListener; import com.ccwangluo.ccim.listener.OnConnectListener;
import com.ccwangluo.ccim.listener.OnPlayAudioCallback; import com.ccwangluo.ccim.listener.OnPlayAudioCallback;
...@@ -71,9 +73,9 @@ public class CCIMClient { ...@@ -71,9 +73,9 @@ public class CCIMClient {
private CCIMClient() { private CCIMClient() {
callBackManager = new CallBackManager<>(); callBackManager = new CallBackManager<>();
socketManager = new SocketManager(callBackManager, executor); socketManager = new SocketManager(callBackManager, executor);
contactManager = new ContactManager(socketManager, callBackManager);
channelManager = new ChannelManager(socketManager, callBackManager); channelManager = new ChannelManager(socketManager, callBackManager);
messageManager = new MessageManager(socketManager, callBackManager, executor); messageManager = new MessageManager(socketManager, callBackManager, executor);
contactManager = new ContactManager(socketManager, callBackManager, messageManager,executor);
} }
private static CCIMClient mInstance; private static CCIMClient mInstance;
...@@ -94,7 +96,7 @@ public class CCIMClient { ...@@ -94,7 +96,7 @@ public class CCIMClient {
} }
public void initSDK(Context context, String appKey, String userName, String extData, Long userId, Long ts, String sign, String server, OnConnectListener resultCallback) { public void initSDK(Context context, String appKey, String userName, String extData, Long userId, Long ts, String sign, String server, OnConnectListener resultCallback) {
this.user = new User(userId,userName,extData); this.user = new User(userId, userName, extData);
messageManager.init(context, userId); messageManager.init(context, userId);
socketManager.initChat(context, appKey, userName, extData, userId, ts, sign, server, new OnClientConnectListener() { socketManager.initChat(context, appKey, userName, extData, userId, ts, sign, server, new OnClientConnectListener() {
@Override @Override
...@@ -228,7 +230,7 @@ public class CCIMClient { ...@@ -228,7 +230,7 @@ public class CCIMClient {
String username = pushContactNewReqRes.getContactNewReq().getUsername(); String username = pushContactNewReqRes.getContactNewReq().getUsername();
Long id = pushContactNewReqRes.getContactNewReq().getUserId(); Long id = pushContactNewReqRes.getContactNewReq().getUserId();
String extData = pushContactNewReqRes.getContactNewReq().getExtData(); String extData = pushContactNewReqRes.getContactNewReq().getExtData();
pushMsgListener.pushContactNewReq(new User(id, username,extData)); pushMsgListener.pushContactNewReq(new User(id, username, extData));
} }
if (chatResponseMessage.hasPushUserDeletedRes()) { if (chatResponseMessage.hasPushUserDeletedRes()) {
...@@ -367,8 +369,8 @@ public class CCIMClient { ...@@ -367,8 +369,8 @@ public class CCIMClient {
/** /**
* 同步离线消息 * 同步离线消息
*/ */
private void getOfflineMessage(Long contactId, ResultEventCallback<List<MessageContent>> resultEventCallback) { private void getOfflineMessage(ResultEventCallback<Void> resultEventCallback) {
messageManager.getOfflineMessage(contactId, resultEventCallback); // messageManager.getOfflineMessage(resultEventCallback);
} }
/** /**
...@@ -499,7 +501,7 @@ public class CCIMClient { ...@@ -499,7 +501,7 @@ public class CCIMClient {
runnable = null; runnable = null;
} }
}; };
handler.postDelayed(runnable,maxAudioDuration * 1000L); handler.postDelayed(runnable, maxAudioDuration * 1000L);
} }
@Override @Override
...@@ -550,7 +552,7 @@ public class CCIMClient { ...@@ -550,7 +552,7 @@ public class CCIMClient {
/** /**
* 开始录音 * 开始录音
*/ */
public void startRecordChannelAudioMessage(Context context,Long channelID, ResultEventCallback<Void> resultCallback,RecordAutoSendCallback callback) { public void startRecordChannelAudioMessage(Context context, Long channelID, ResultEventCallback<Void> resultCallback, RecordAutoSendCallback callback) {
PermissionUtils.check(context, Manifest.permission.RECORD_AUDIO, new ResultEventCallback<Void>() { PermissionUtils.check(context, Manifest.permission.RECORD_AUDIO, new ResultEventCallback<Void>() {
@Override @Override
public void onSuccess(Void o) { public void onSuccess(Void o) {
...@@ -576,7 +578,7 @@ public class CCIMClient { ...@@ -576,7 +578,7 @@ public class CCIMClient {
runnable = null; runnable = null;
} }
}; };
handler.postDelayed(runnable,maxAudioDuration * 1000L); handler.postDelayed(runnable, maxAudioDuration * 1000L);
} }
@Override @Override
...@@ -612,7 +614,7 @@ public class CCIMClient { ...@@ -612,7 +614,7 @@ public class CCIMClient {
} }
private boolean checkAudio(ResultEventCallback<MessageContent> callback) { private boolean checkAudio(ResultEventCallback<MessageContent> callback) {
if (runnable != null){ if (runnable != null) {
handler.removeCallbacks(runnable); handler.removeCallbacks(runnable);
runnable = null; runnable = null;
} }
...@@ -653,6 +655,13 @@ public class CCIMClient { ...@@ -653,6 +655,13 @@ public class CCIMClient {
messageManager.getAudioDuration(msgId, downloadPrefix, cachePath, resultCallback); messageManager.getAudioDuration(msgId, downloadPrefix, cachePath, resultCallback);
} }
/**
* 更新已读偏移量
*/
public void updateReadOffset(Long userId, Long msgid, ResultEventCallback<Void> callback) {
messageManager.updateReadOffset(userId, msgid, callback);
}
public void logout() { public void logout() {
isConnected = false; isConnected = false;
......
...@@ -23,6 +23,9 @@ public interface MessageDao { ...@@ -23,6 +23,9 @@ public interface MessageDao {
@Query("SELECT * FROM messagecontent where msgId = :msgId") @Query("SELECT * FROM messagecontent where msgId = :msgId")
MessageContent getMsgById(Long msgId); MessageContent getMsgById(Long msgId);
@Query("SELECT * FROM messagecontent where senderUserId = :userId or reciveUserId = :userId") @Query("SELECT * FROM messagecontent order by msgId desc limit 1")
MessageContent getLastMsgById(Long userId); MessageContent getLastMsgById();
@Query("SELECT count(*) FROM messagecontent where senderUserId = :userId and msgId > :msgId")
Long selectOfflineCount(Long userId,Long msgId);
} }
...@@ -8,6 +8,7 @@ import com.ccwangluo.ccim.modle.Contact; ...@@ -8,6 +8,7 @@ import com.ccwangluo.ccim.modle.Contact;
import com.ccwangluo.ccim.modle.ContactGroup; import com.ccwangluo.ccim.modle.ContactGroup;
import com.ccwangluo.ccim.modle.ContactRequestsRes; import com.ccwangluo.ccim.modle.ContactRequestsRes;
import com.ccwangluo.ccim.modle.Dialog; import com.ccwangluo.ccim.modle.Dialog;
import com.ccwangluo.ccim.modle.MessageContent;
import com.ccwangluo.ccim.modle.NetStatus; import com.ccwangluo.ccim.modle.NetStatus;
import com.ccwangluo.ccim.modle.PullContactsRes; import com.ccwangluo.ccim.modle.PullContactsRes;
import com.ccwangluo.ccim.modle.SearchRes; import com.ccwangluo.ccim.modle.SearchRes;
...@@ -19,6 +20,7 @@ import java.util.HashMap; ...@@ -19,6 +20,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.logging.Logger; import java.util.logging.Logger;
import ccim.protocol.Chat; import ccim.protocol.Chat;
...@@ -28,15 +30,20 @@ public class ContactManager { ...@@ -28,15 +30,20 @@ public class ContactManager {
private final Logger logger = Logger.getLogger(CCIMClient.class.getName()); private final Logger logger = Logger.getLogger(CCIMClient.class.getName());
private SocketManager socketManager; private SocketManager socketManager;
private CallBackManager<Chat.ChatResponseMessage> callBackManager; private CallBackManager<Chat.ChatResponseMessage> callBackManager;
private MessageManager messageManager;
private ExecutorService executor;
private final HashMap<Long, Contact> contacts = new HashMap<>(); //联系人列表 private final HashMap<Long, Contact> contacts = new HashMap<>(); //联系人列表
private final HashMap<Long, ContactGroup> contactGroups = new HashMap<>(); //群组列表 private final HashMap<Long, ContactGroup> contactGroups = new HashMap<>(); //群组列表
private final HashMap<Long, Dialog> dialogs = new HashMap<>(); //对话列表 private final HashMap<Long, Dialog> dialogs = new HashMap<>(); //对话列表
private final HashSet<Long> blocklist = new HashSet<Long>(); //对话列表 private final HashSet<Long> blocklist = new HashSet<Long>(); //对话列表
public ContactManager(SocketManager socketManager, CallBackManager<Chat.ChatResponseMessage> callBackManager) {
public ContactManager(SocketManager socketManager, CallBackManager<Chat.ChatResponseMessage> callBackManager, MessageManager messageManager, ExecutorService executor) {
this.socketManager = socketManager; this.socketManager = socketManager;
this.callBackManager = callBackManager; this.callBackManager = callBackManager;
this.messageManager = messageManager;
this.executor = executor;
} }
...@@ -45,7 +52,7 @@ public class ContactManager { ...@@ -45,7 +52,7 @@ public class ContactManager {
*/ */
public void getContactList(ResultEventCallback<PullContactsRes> resultEventCallback, boolean isClearCache) { public void getContactList(ResultEventCallback<PullContactsRes> resultEventCallback, boolean isClearCache) {
if (!isClearCache && (contacts.size() > 0 || contactGroups.size() > 0 || dialogs.size() > 0)) { if (!isClearCache && (contacts.size() > 0 || contactGroups.size() > 0 || dialogs.size() > 0)) {
PullContactsRes pullContactsRes = new PullContactsRes(contactGroups.values(),contacts.values(),dialogs.values(),blocklist); PullContactsRes pullContactsRes = new PullContactsRes(contactGroups.values(), contacts.values(), dialogs.values(), blocklist);
resultEventCallback.onSuccess(pullContactsRes); resultEventCallback.onSuccess(pullContactsRes);
return; return;
} }
...@@ -85,7 +92,28 @@ public class ContactManager { ...@@ -85,7 +92,28 @@ public class ContactManager {
if (pullContactsRes1.getBlocklist() != null) { if (pullContactsRes1.getBlocklist() != null) {
blocklist.addAll(pullContactsRes1.getBlocklist()); blocklist.addAll(pullContactsRes1.getBlocklist());
} }
resultEventCallback.onSuccess(new PullContactsRes(contactGroups.values(),contacts.values(),dialogs.values(),blocklist));
messageManager.getOfflineMessage(new ResultEventCallback<Void>() {
@Override
public void onSuccess(Void unused) {
executor.execute(new Runnable() {
@Override
public void run() {
for (Long aLong : dialogs.keySet()) {
Dialog dialog = dialogs.get(aLong);
Long offlineMessageCountByUserId = messageManager.getOfflineMessageCountByUserId(aLong, dialog.getReadMsgId());
dialog.setUnReadMsgNum(offlineMessageCountByUserId == null ? 0 : offlineMessageCountByUserId);
}
resultEventCallback.onSuccess(new PullContactsRes(contactGroups.values(), contacts.values(), dialogs.values(), blocklist));
}
});
}
@Override
public void onFailed(int errorCode) {
resultEventCallback.onFailed(errorCode);
}
});
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -20,6 +20,7 @@ import com.google.protobuf.InvalidProtocolBufferException; ...@@ -20,6 +20,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat; import com.google.protobuf.util.JsonFormat;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.logging.Logger; import java.util.logging.Logger;
...@@ -52,16 +53,33 @@ public class MessageManager { ...@@ -52,16 +53,33 @@ public class MessageManager {
} }
private List<MessageContent> messageContentList = new ArrayList<>();
/** /**
* 同步离线消息 * 同步离线消息
*/ */
public void getOfflineMessage(Long contactId, ResultEventCallback<List<MessageContent>> resultEventCallback) { public void getOfflineMessage(ResultEventCallback<Void> resultEventCallback) {
executor.execute(() -> { executor.execute(() -> {
long lastPullMsgId = 0; long lastPullMsgId = 0;
MessageContent lastMsgById = db.messageDao().getLastMsgById(contactId); MessageContent lastMsgById = db.messageDao().getLastMsgById();
if (lastMsgById != null) { if (lastMsgById != null) {
lastPullMsgId = lastMsgById.getMsgId(); lastPullMsgId = lastMsgById.getMsgId();
} }
messageContentList.clear();
getOfflineMessageOnce(lastPullMsgId, new ResultEventCallback<Void>() {
@Override
public void onSuccess(Void unused) {
resultEventCallback.onSuccess(null);
}
@Override
public void onFailed(int errorCode) {
resultEventCallback.onFailed(errorCode);
}
});
});
}
public void getOfflineMessageOnce(Long lastPullMsgId,ResultEventCallback<Void> callback) {
Message.PullOfflineMessageRequest offlineMessageRequest = Message.PullOfflineMessageRequest.newBuilder() Message.PullOfflineMessageRequest offlineMessageRequest = Message.PullOfflineMessageRequest.newBuilder()
.setLastPulledMsgId(lastPullMsgId) .setLastPulledMsgId(lastPullMsgId)
.build(); .build();
...@@ -78,13 +96,23 @@ public class MessageManager { ...@@ -78,13 +96,23 @@ public class MessageManager {
String print = JsonFormat.printer().print(chatResponseMessage.getPullOfflineMsgRes()); String print = JsonFormat.printer().print(chatResponseMessage.getPullOfflineMsgRes());
PullOffLineMessageRes pullOffLineMessageRes = gson.fromJson(print, PullOffLineMessageRes.class); PullOffLineMessageRes pullOffLineMessageRes = gson.fromJson(print, PullOffLineMessageRes.class);
List<MessageContent> message = pullOffLineMessageRes.getOfflineMessages(); List<MessageContent> message = pullOffLineMessageRes.getOfflineMessages();
if (message == null){
callback.onSuccess(null);
return;
}
for (MessageContent messageContent : message) { for (MessageContent messageContent : message) {
if (!messageContent.getSenderUserId().equals(userId)) { if (!messageContent.getSenderUserId().equals(userId)) {
messageContent.setReciveUserId(userId); messageContent.setReciveUserId(userId);
} }
} }
resultEventCallback.onSuccess(message); messageContentList.addAll(message);
pushNewMessageList(message); pushNewMessageList(message);
Long msgId = message.get(message.size() - 1).getMsgId();
if (message.size() > 0 && msgId<= lastPullMsgId){
getOfflineMessageOnce(msgId,callback);
} else {
callback.onSuccess(null);
}
} catch (InvalidProtocolBufferException e) { } catch (InvalidProtocolBufferException e) {
e.printStackTrace(); e.printStackTrace();
} }
...@@ -93,12 +121,9 @@ public class MessageManager { ...@@ -93,12 +121,9 @@ public class MessageManager {
@Override @Override
public void onFailed(int errorCode) { public void onFailed(int errorCode) {
resultEventCallback.onFailed(errorCode); callback.onFailed(errorCode);
} }
}); });
});
} }
...@@ -123,7 +148,7 @@ public class MessageManager { ...@@ -123,7 +148,7 @@ public class MessageManager {
String text = content; String text = content;
if (messageType == MessageSpec.MessageType.MESSAGE_TYPE_TEXT) { if (messageType == MessageSpec.MessageType.MESSAGE_TYPE_TEXT) {
text = sendMsgRes.getContent(); text = sendMsgRes.getContent();
} else if (messageType == MessageSpec.MessageType.MESSAGE_TYPE_VOICE){ } else if (messageType == MessageSpec.MessageType.MESSAGE_TYPE_VOICE) {
message.setVoiceContent(sendMsgRes.getContent()); message.setVoiceContent(sendMsgRes.getContent());
} }
message.setSenderUserId(userId); message.setSenderUserId(userId);
...@@ -167,7 +192,7 @@ public class MessageManager { ...@@ -167,7 +192,7 @@ public class MessageManager {
String text = content; String text = content;
if (messageType == MessageSpec.MessageType.MESSAGE_TYPE_TEXT) { if (messageType == MessageSpec.MessageType.MESSAGE_TYPE_TEXT) {
text = sendMsgRes.getContent(); text = sendMsgRes.getContent();
} else if (messageType == MessageSpec.MessageType.MESSAGE_TYPE_VOICE){ } else if (messageType == MessageSpec.MessageType.MESSAGE_TYPE_VOICE) {
message.setVoiceContent(sendMsgRes.getContent()); message.setVoiceContent(sendMsgRes.getContent());
} }
message.setSenderUserId(userId); message.setSenderUserId(userId);
...@@ -382,15 +407,15 @@ public class MessageManager { ...@@ -382,15 +407,15 @@ public class MessageManager {
} }
public long getDuration(String path){ public long getDuration(String path) {
android.media.MediaMetadataRetriever mmr = new android.media.MediaMetadataRetriever(); android.media.MediaMetadataRetriever mmr = new android.media.MediaMetadataRetriever();
long duration=0; long duration = 0;
try { try {
if (path!= null) { if (path != null) {
mmr.setDataSource(path); mmr.setDataSource(path);
} }
String time = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); String time = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
duration= Long.parseLong(time); duration = Long.parseLong(time);
} catch (Exception ex) { } catch (Exception ex) {
} finally { } finally {
mmr.release(); mmr.release();
...@@ -398,4 +423,25 @@ public class MessageManager { ...@@ -398,4 +423,25 @@ public class MessageManager {
return duration; return duration;
} }
public void updateReadOffset(Long userId, Long msgid, ResultEventCallback<Void> callback) {
Chat.ChatRequestMessage.Builder builder = Chat.ChatRequestMessage.newBuilder();
Message.UpdateReadOffsetRequest build = Message.UpdateReadOffsetRequest.newBuilder().setContactUserId(userId).setMsgId(msgid).build();
builder.setUpdateReadOffsetReq(build);
int id = socketManager.sendRequest(builder);
callBackManager.addCallBack(id, new ResultEventCallback<Chat.ChatResponseMessage>() {
@Override
public void onSuccess(Chat.ChatResponseMessage chatResponseMessage) {
callback.onSuccess(null);
}
@Override
public void onFailed(int errorCode) {
callback.onFailed(errorCode);
}
});
}
public Long getOfflineMessageCountByUserId(Long userId,Long msgId) {
return db.messageDao().selectOfflineCount(userId,msgId);
}
} }
...@@ -10,6 +10,24 @@ public class Dialog { ...@@ -10,6 +10,24 @@ public class Dialog {
private DialogType dialogType; private DialogType dialogType;
private NetStatus netStatus = NetStatus.NET_STATUS_ONLINE; private NetStatus netStatus = NetStatus.NET_STATUS_ONLINE;
private String extData; private String extData;
private Long readMsgId;
private Long unReadMsgNum;
public Long getUnReadMsgNum() {
return unReadMsgNum;
}
public void setUnReadMsgNum(Long unReadMsgNum) {
this.unReadMsgNum = unReadMsgNum;
}
public Long getReadMsgId() {
return readMsgId;
}
public void setReadMsgId(Long readMsgId) {
this.readMsgId = readMsgId;
}
public Long getContactUserId() { public Long getContactUserId() {
return contactUserId; return contactUserId;
......
syntax = "proto3";
package ccim.protocol;
import "common.proto";
message AuthRequestMessage {
RequestMessageHeader header = 1;
LoginRequest login_req = 2;
LogoutRequest logout_req = 3;
};
message AuthResponseMessage {
ResponseMessageHeader header = 1;
LoginResponse login_res = 2;
LogoutResponse logout_res = 3;
}
message LoginRequest {
string username = 1;
string password = 2;
int64 app_id = 3;
}
message LoginResponse {
string token = 1;
string server = 2;
}
message LogoutRequest {
}
message LogoutResponse {
}
\ No newline at end of file
...@@ -2,6 +2,8 @@ syntax = "proto3"; ...@@ -2,6 +2,8 @@ syntax = "proto3";
package ccim.protocol; package ccim.protocol;
option csharp_namespace = "CCIM.Protocol";
message CreateChannelRequest { message CreateChannelRequest {
string name = 1; string name = 1;
string tag = 2; string tag = 2;
......
...@@ -2,6 +2,8 @@ syntax = "proto3"; ...@@ -2,6 +2,8 @@ syntax = "proto3";
package ccim.protocol; package ccim.protocol;
option csharp_namespace = "CCIM.Protocol";
import "channel.proto"; import "channel.proto";
import "common.proto"; import "common.proto";
import "contact.proto"; import "contact.proto";
...@@ -24,6 +26,7 @@ message ChatRequestMessage { ...@@ -24,6 +26,7 @@ message ChatRequestMessage {
DeleteContactGroupRequest delete_contact_group_req = 10; // 删除联系人组 DeleteContactGroupRequest delete_contact_group_req = 10; // 删除联系人组
DeleteContactRequest delete_contact_req = 11; // 删除联系人 DeleteContactRequest delete_contact_req = 11; // 删除联系人
PullOfflineMessageRequest pull_offline_msg_req = 12; // 拉取离线消息 PullOfflineMessageRequest pull_offline_msg_req = 12; // 拉取离线消息
UpdateReadOffsetRequest update_read_offset_req = 13; // 更新已读偏移量
CreateChannelRequest create_channel_req = 21; // 创建频道 CreateChannelRequest create_channel_req = 21; // 创建频道
JoinChannelRequest join_channel_req = 22; // 加入频道 JoinChannelRequest join_channel_req = 22; // 加入频道
...@@ -64,6 +67,7 @@ message ChatResponseMessage { ...@@ -64,6 +67,7 @@ message ChatResponseMessage {
DeleteContactGroupResponse delete_contact_group_res = 10; DeleteContactGroupResponse delete_contact_group_res = 10;
DeleteContactResponse delete_contact_res = 11; DeleteContactResponse delete_contact_res = 11;
PullOfflineMessageResponse pull_offline_msg_res = 12; PullOfflineMessageResponse pull_offline_msg_res = 12;
UpdateReadOffsetResponse update_read_offset_res = 13;
CreateChannelResponse create_channel_res = 21; CreateChannelResponse create_channel_res = 21;
JoinChannelResponse join_channel_res = 22; JoinChannelResponse join_channel_res = 22;
......
...@@ -2,6 +2,8 @@ syntax = "proto3"; ...@@ -2,6 +2,8 @@ syntax = "proto3";
package ccim.protocol; package ccim.protocol;
option csharp_namespace = "CCIM.Protocol";
enum StatusCode { enum StatusCode {
STATUS_CODE_OK = 0; // 正常 STATUS_CODE_OK = 0; // 正常
......
...@@ -2,6 +2,8 @@ syntax = "proto3"; ...@@ -2,6 +2,8 @@ syntax = "proto3";
package ccim.protocol; package ccim.protocol;
option csharp_namespace = "CCIM.Protocol";
enum NetStatus { enum NetStatus {
NET_STATUS_ONLINE = 0; NET_STATUS_ONLINE = 0;
NET_STATUS_OFFLINE = 1; NET_STATUS_OFFLINE = 1;
...@@ -30,6 +32,8 @@ message Dialog { ...@@ -30,6 +32,8 @@ message Dialog {
DialogType dialog_type = 6; // 对话类型 DialogType dialog_type = 6; // 对话类型
NetStatus net_status = 7; // 网络状态 NetStatus net_status = 7; // 网络状态
string ext_data = 8; // 扩展数据 string ext_data = 8; // 扩展数据
int64 read_msg_id = 9; // 已读消息id
} }
/** /**
......
...@@ -2,6 +2,8 @@ syntax = "proto3"; ...@@ -2,6 +2,8 @@ syntax = "proto3";
package ccim.protocol; package ccim.protocol;
option csharp_namespace = "CCIM.Protocol";
import "message_spec.proto"; import "message_spec.proto";
message SendMessageRequest { message SendMessageRequest {
...@@ -51,3 +53,11 @@ message PullChannelMessageRequest { ...@@ -51,3 +53,11 @@ message PullChannelMessageRequest {
message PullChannelMessageResponse { message PullChannelMessageResponse {
repeated ChatMessage message = 1; repeated ChatMessage message = 1;
} }
message UpdateReadOffsetRequest {
int64 msg_id = 1;
int64 contact_user_id = 2;
}
message UpdateReadOffsetResponse {
}
\ No newline at end of file
...@@ -2,6 +2,8 @@ syntax = "proto3"; ...@@ -2,6 +2,8 @@ syntax = "proto3";
package ccim.protocol; package ccim.protocol;
option csharp_namespace = "CCIM.Protocol";
enum MessageType { enum MessageType {
MESSAGE_TYPE_TEXT = 0; MESSAGE_TYPE_TEXT = 0;
MESSAGE_TYPE_VOICE = 1; MESSAGE_TYPE_VOICE = 1;
......
...@@ -2,6 +2,8 @@ syntax = "proto3"; ...@@ -2,6 +2,8 @@ syntax = "proto3";
package ccim.protocol; package ccim.protocol;
option csharp_namespace = "CCIM.Protocol";
import "contact.proto"; import "contact.proto";
import "message_spec.proto"; import "message_spec.proto";
......
...@@ -2,6 +2,8 @@ syntax = "proto3"; ...@@ -2,6 +2,8 @@ syntax = "proto3";
package ccim.protocol; package ccim.protocol;
option csharp_namespace = "CCIM.Protocol";
message BlockUserRequest { message BlockUserRequest {
int64 blocked_user_id = 1; int64 blocked_user_id = 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment