【网易云信】自行实现陌生人防打扰功能

网易云信实现陌生人防打扰功能,即屏蔽陌生人消息。不可以给陌生人发消息
要求如下:

1、如对方开启了陌生人消息保护且你不是对方关注的用户,则发送给对方消息时系统通知:对方开启了陌生人消息保护,您发出的消息将不会被收到,每次都提示。
2、当陌生人首次给你发送消息时弹出此系统通知(对方为陌生人,您可以在我的-设置-消息设置中拒收此类消息),每个用户只弹出一次

首先数一下陌生人定义(自行定义):

陌生人定义:A关注了B,那么A不是B的陌生人,B可以给A发消息。即我的粉丝不是我的陌生人
陌生人有点绕口。可以用关注来代替陌生人的概念

一、我给用户A发消息

1、效果图如下:

在这里插入图片描述

2、逻辑流程如下:

在这里插入图片描述

3、我查看用户A资料,在用户A资料中返回:is_can_send
即:
false:用户A开启陌生人保护+用户A没有关注我
true:1、用户A没有开启陌生人保护
	  2、用户A开启陌生人保护+用户A关注了我
4、将输入框(InputPanel类)发送消息,取消直接发送(群聊的不处理),将事件回调到单聊界面。
	// 发送文本消息
    private void onTextMessageSendButtonPressed() {
        String text = messageEditText.getText().toString().trim();
        if (container.sessionType==SessionTypeEnum.Team){
            IMMessage textMessage = createTextMessage(text);
            if (container.proxy.sendMessage(textMessage)) {
                restoreText(true);
            }
        }else {
            if (callbackInputClick != null) {
                callbackInputClick.OnSendMessage(text);
            }
        }
    }
5、进入单聊界面每次发送消息时候。判断是否可以发送,不能发送的本地插入消息。
	  @Override
      public void OnSendMessage(String text) {
        if (fragment == null) {
             return;
         }
        if (isCanSendMsg) {
            IMMessage textMessage = MessageBuilder.createTextMessage(fragment.container.account, fragment.container.sessionType, text);
             if (fragment.container.proxy.sendMessage(textMessage)) {
                 fragment.restoreText();
             }
          } else {
             fragment.addLocalMsg("对方开启了陌生人消息保护,您发出的消息将不会被收到");
             fragment.restoreText();
         }
     }
 // 本地插入自定义消息
    public void addMessage(String text) {
        container.activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                MyOrderGroupAttachment attachment = new MyOrderGroupAttachment();
                attachment.setContent(text);
                IMMessage message = MessageBuilder.createCustomMessage(container.account, SessionTypeEnum.P2P, attachment);
                message.setStatus(MsgStatusEnum.success);
                CustomMessageConfig config = new CustomMessageConfig();
                config.enableUnreadCount = false;
                message.setConfig(config);
                NIMClient.getService(MsgService.class).saveMessageToLocal(message, true);
            }
        });
    }

二、用户A给我发消息

1、效果图如下:

在这里插入图片描述

2、逻辑流程如下:

在这里插入图片描述

3、当我打开与用户A聊天界面时,查看用户A资料,在用户A资料中返回:is_need_notify(是否需要展示提示语,不包含首次的判断)
即:
true:我开启陌生人保护+我没有关注用户A
false:1、我没有开启陌生人保护
	  2、我开启陌生人保护+我关注了用户A
4、获取给我发消息的时间点,回传到私聊界面去判断是否需要提示语

此处有2种情况:

1、没有在App单聊页面,在其他页面
2、在App单聊界面
3、App杀死的情况下

我们发现不论在那个页面。最近联系人列表都会发生改变。我们可以在最近联系人列表页面中做监听(需要监听两个地方observeReceiveMessage,observeRecentContact)。接收到消息,然后通知私聊界面去判断是否需要展示消息。

最近联系人界面(RecentContactsFragment):如果满足条件,回调到FragmentMessage页面。

监听位置1:service.observeReceiveMessage(messageReceiverObserver, register);

	//监听在线消息
    private Observer<List<IMMessage>> messageReceiverObserver = new Observer<List<IMMessage>>() {
        @Override
        public void onEvent(List<IMMessage> imMessages) {
            if (imMessages != null) {
                String key = imMessages.get(0).getFromAccount() + SharedPreferencesUtil.getUserInfo(getContext(), "accid");
                //之前没有发送过消息
                if ("N".equals(SharedPreferencesUtil.getPrefString(getContext(), key, "N"))) {
                    SharedPreferencesUtil.setPrefString(getContext(), key, "Y");
                    //消息列表~仅仅是第一次收到消息,是否需要展示提示,到私聊页面判断
                    if (callBackUnreadNum != null) {
                        callBackUnreadNum.isSendNotify();
                    }
                } 
				//其余消息的正常操作
            }
        }
    };

监听位置2:service.observeRecentContact(messageObserver, register);
此种情况是为了防止APP杀死情况下不能收到回调。

 Observer<List<RecentContact>> messageObserver = new Observer<List<RecentContact>>() {
        @Override
        public void onEvent(List<RecentContact> recentContacts) {
            if (recentContacts != null && recentContacts.size() > 0) {
                RecentContact recentContact = recentContacts.get(0);
                String key = recentContact.getFromAccount() + SharedPreferencesUtil.getUserInfo(getContext(), "accid");
               //处理同上面方法   保存sp
            }
               //其余消息的正常操作
                return;
            }
            onRecentContactChanged(recentContacts);
        }
    };

在FragmentMessage页面中,通过EventBus通知私聊界面去判断(如果此时正在私聊界面的话)

//当打开了单聊界面的时候.发送消息.提示陌生人保护
            @Override
            public void isSendNotify() {
                EventBus.getDefault().post(new IEvent(LxKeys.EVENT_SEND_NOTIFY, ""));
                Log.d("tag", "发送回调刷新消息");
            }

还要注意首次问题。可以通过SharedPreferences进行判断
key

发送id+接收方id

取出的值

N:之前没有发送过消息
Y:第一次收到消息,需要到私聊界面判断是否应该展示提示
M:已经接收到消息,并且提示过了。

5、私聊界面去判断

因为此处有2种情况:

1、没有在App单聊页面,在其他页面
2、在App单聊界面

我们需要在两个地方去判断

1、当我们请求完对方的个人资料时候,就需要去判断一下是否需要展示提示语。
2、接收到EventBus通知时候

如果需要提示,提示完成,则将sp值改为M,逻辑如下:

	private void sendNotify() {
        if (isNeedShowMsg) {
            if ("Y".equals(SharedPreferencesUtil.getPrefString(MessageP2PActivity.this, notify_key, ""))) {
                fragment.addLocalMsg("对方为陌生人,您可以在我的-设置-消息设置中拒收此类消息");
                SharedPreferencesUtil.setPrefString(MessageP2PActivity.this, notify_key, "M");
            }
        } 
    }

ok,万事大吉!

发布了49 篇原创文章 · 获赞 46 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/mingtiannihao0522/article/details/103736884