美文网首页
网易云信 即时聊天

网易云信 即时聊天

作者: 苏坡坡要吃婆婆酥 | 来源:发表于2020-07-23 10:51 被阅读0次

    1.状态栏消息通知展示

    在使用demo测试的时候可能会发现配置完死活都不弹出消息通知。
    不要慌,首先确认通知权限是否打开。
    然后,将demo切换到后台,看是否能收到通知。因为demo的写法是处于后台时候才会通知。

    (1) 先进行配置
    StatusBarNotificationConfig config = new StatusBarNotificationConfig();
    // 点击通知需要跳转到的界面
    // 这里就只演示一下常规配置
    config.notificationEntrance = NoViewActivity.class;
    NIMClient.updateStatusBarNotificationConfig(config);
    
    (2) 开启通知
    // 开启通知栏消息提醒
    NIMClient.toggleNotification(true);
    
    (3) 在页面内设置*
    // 进入聊天界面,建议放在onResume中。表示来自account的消息无需进行消息提醒。
    NIMClient.getService(MsgService.class).setChattingAccount(account, sessionType);
    
    // 进入最近联系人列表界面,建议放在onResume中。表示所有消息无需进行消息提醒。
    NIMClient.getService(MsgService.class).setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_ALL, SessionTypeEnum.None);
    
    // 退出聊天界面或离开最近联系人列表界面,建议放在onPause中。表示所有消息都可以进行消息提醒。
    NIMClient.getService(MsgService.class).setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_NONE, SessionTypeEnum.None);
    
    

    就这样操作三步就可以收到消息通知了。
    一般我们集成的是UiKit的库,在项目中直接加载库中最近会话列表和聊天页面等,聊天页面的通知已经默认做好,我们无需操作。
    如果要全程收到通知,我们在主页设置一下代码就好了。

    NIMClient.getService(MsgService.class).setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_NONE, SessionTypeEnum.None);
    
    

    2.状态栏消息通知的点击事件

    demo里面的写法是跳到启动页然后根据intent获取的参数继续跳聊天页。
    正常情况下我们启动页已经写好了,再改起来有点麻烦。
    所以我们直接可以写一个没有视图的空页面只做跳转。
    有同学可能会疑惑为什么不能直接跳到主页面然后再操作呢。因为我们一般主页面都会设置为signTask,当前页面存在情况下再次跳转拿不到new Intent。

    NoViewActivity局步代码

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            onParseIntent();
        }
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            onParseIntent();
        }
    
        private void onParseIntent() {
            Intent intent = getIntent();
            if (intent.hasExtra(NimIntent.EXTRA_NOTIFY_CONTENT)) {
                ArrayList<IMMessage> messages = (ArrayList<IMMessage>)
                        getIntent().getSerializableExtra(NimIntent.EXTRA_NOTIFY_CONTENT); // 可以获取消息的发送者,跳转到指定的单聊、群聊界面。
                if (messages == null || messages.size() == 0) {
                    finish();
                    return;
                }
                intent.removeExtra(NimIntent.EXTRA_NOTIFY_CONTENT);
                switch (messages.get(0).getSessionType()) {
                    case P2P:
                        NimUIKit.startP2PSession(this, messages.get(0).getSessionId());
                        break;
                }
            }
            finish();
        }
    
    

    3. 自定义消息(分享名片,分享文章等等)

    根据UiKit中的文档可以看到分为九个步骤。
    下面我们演示一下分享名片。

    首先,先定义一个自定义消息的类型

    public interface CustomAttachmentType {
        int ShareUserType = 1;
    }
    

    第二步,定义一个自定义消息附件的基类,负责解析你的自定义消息的公用字段,比如类型等 。

    注意: 实现 MsgAttachment 接口的成员都要实现 Serializable。

    public abstract class CustomAttachment implements MsgAttachment {
        protected int type;
        CustomAttachment(int type) {
            this.type = type;
        }
        public void fromJson(JSONObject data) {
            if (data != null) {
                parseData(data);
            }
        }
        @Override
        public String toJson(boolean send) {
            return CustomAttachParser.packData(type, packData());
        }
        public int getType() {
            return type;
        }
        protected abstract void parseData(JSONObject data);
        protected abstract JSONObject packData();
    }
    

    第三步,继承这个基类,实现“名片”的附件类型。

    注意,成员变量都要实现 Serializable。

    public class ShareUserAttachment extends CustomAttachment {
    
        private String userIcon;
        private String userName;
        private String userId;
    
    
        public ShareUserAttachment() {
            super(CustomAttachmentType.ShareUserMsg);
        }
    
        public ShareUserAttachment(String str) {
            this();
        }
    
        @Override
        protected void parseData(JSONObject data) {
          //括号里的这三个字段跟IOS端或者其他端商议好
            userName = data.getString("shareTitle");
            userIcon= data.getString("shareIcon");
            userId = data.getString("shareId");
        }
    
        @Override
        public JSONObject packData() {
            //括号里的这三个字段跟IOS端或者其他端商议好
            JSONObject data = new JSONObject();
            data.put("shareTitle", userName);
            data.put("shareIcon", userIcon);
            data.put("shareId", userId);
            return data;
        }
    
        public String getUserIcon() {
            return userIcon;
        }
    
        public void setUserIcon(String userIcon) {
            this.userIcon= userIcon;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
    
        public String getUserId() {
            return userId;
        }
    
        public void setUserId(String userId) {
            this.userId = userId;
        }
    }
    

    第四步,实现自定义消息的附件解析器。

    public class CustomAttachParser implements MsgAttachmentParser {
        private static final String KEY_TYPE = "type";
        private static final String KEY_DATA = "data";
        @Override
        public MsgAttachment parse(String json) {
            CustomAttachment attachment = null;
            try {
                JSONObject object = JSON.parseObject(json);
                int type = object.getInteger(KEY_TYPE);
                JSONObject data = object.getJSONObject(KEY_DATA);
                switch (type) {
                        case CustomAttachmentType.ShareUserType :
                        attachment = new ShareUserAttachment();
                        break;
                }
                if (attachment != null) {
                    //注意了,按照Android UiKit文档里的写法自定义消息的参数是包在data字段里面的。IOS文档里面的写法没有包。
                    //如果不需要data字段,此处直接解析object 
                    //attachment.fromJson(object);
                    attachment.fromJson(data);
                }
            } catch (Exception e) {
    
            }
            return attachment;
        }
        public static String packData(int type, JSONObject data) {
            JSONObject object = new JSONObject();
            object.put(KEY_TYPE, type);
            if (data != null) {
                 //包装在data里面的写法
                object.put(KEY_DATA, data);
                //不放在data 直接放在外层
    //            for (Map.Entry<String, Object> objectEntry : data.entrySet()) {
    //                object.put(objectEntry.getKey(), objectEntry.getValue());
    //            }
            }
            return object.toJSONString();
        }
    }
    

    第五步,将自定义消息UI

    public class ShareUserViewHolder extends MsgViewHolderBase {
    
        private ImageView ivUser;
        private TextView tvName;
        private ShareUserAttachment attachment;
        private RelativeLayout rlItem;
    
        public ShareUserViewHolder(BaseMultiItemFetchLoadAdapter adapter) {
            super(adapter);
        }
    
        @Override
        public int getContentResId() {
            return R.layout.item_msg_share_user;
        }
    
        @Override
        public void inflateContentView() {
            rlItem = (RelativeLayout) findViewById(R.id.rl_item);
            ivUser = (ImageView) findViewById(R.id.iv_user);
            tvName = (TextView) findViewById(R.id.tv_name);
        }
    
        @Override
        public void bindContentView() {
            attachment = (ShareUserAttachment) message.getAttachment();
    
            Glide.with(context).load(attachment.getUrl()).into(ivUser);
            tvName.setText(attachment.getUserName());
            rlItem.setOnClickListener(lis -> {
    
            //这是一个隐藏键盘的方法,不需要自行去掉
            InputMethodManager imm = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE);
            View v = ((AppCompatActivity) context).getWindow().peekDecorView();
            if (null != v) {
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }
    
          //点击事件
           context.startActivity(new Intent(context, OtherUserActivity.class)
                        .putExtra("userId", attachment.getUserId()));
            });
        }
    
        // 若是要自己修改气泡背景自行替换,当前为0表示没有
        // 当是发送出去的消息时,内容区域背景的drawable id
        @Override
        protected int rightBackground() {
            return 0;
        }
    
        @Override
        protected int leftBackground() {
            return 0;
        }
    
    }
    

    第六步,发送自定义消息。
    文档里的写法是从聊天页面底部菜单的更多菜单位置发送的。可自行琢磨。当前写法直接用非聊天页面分享。

        ShareUserAttachment userAttachment = new ShareUserAttachment();
        userAttachment.setUserId(shareUserId);
        userAttachment.setUserName(shareUserName);
        userAttachment.setUserIcon(shareIcon);
    
        IMMessage message = MessageBuilder.createCustomMessage(account, SessionTypeEnum.P2P, userAttachment);
    
         //发送自定义消息
         NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback<Void>() {
                @Override
                public void onSuccess(Void param) {
    
                }
    
                @Override
                public void onFailed(int code) {
                   
                }
    
                @Override
                public void onException(Throwable exception) {
    
                }
            });
    
    

    第七步,将该附件解析器注册到 SDK 中。为了保证生成历史消息时能够正确解析自定义附件,注册一般应放在 Application 的 onCreate 中完成

    NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser());
    
    

    第八步,注册扩展消息类型的显示ViewHolder,由于这里使用我们UIKIT,所以也需要注册到Application的onCreate中

     NimUIKit.registerMsgItemViewHolder(ShareUserAttachment.class, ShareUserViewHolder .class);
    
    

    第九步,我们暂时不需要从聊天底部菜单中发送所以省略。

    4. 自定义聊天气泡,聊天界面时间显示,已读显示等

    一下操作都是在MyApplication中进行

            // ... your codes
            if (NIMUtil.isMainProcess(this)) {
                // 注意:以下操作必须在主进程中进行
                // 1、UI相关初始化操作
                // 初始化
                NimUIKit.init(this, buildUIKitOptions());
            }
    
    
        private UIKitOptions buildUIKitOptions() {
            UIKitOptions options = new UIKitOptions();
            //自定义聊天界面消息气泡
            options.messageLeftBackground = R.drawable.shape_msg_text_bg_receive;
            options.messageRightBackground = R.drawable.shape_msg_text_bg_send;
    
            //消息列表每隔多久显示一条消息  默认五分钟,当前设置一小时
            options.displayMsgTimeWithInterval = 60 * 60 * 1000;
            //全局是否使用消息已读 
            options.shouldHandleReceipt = false;
            return options;
        }
    
    

    相关文章

      网友评论

          本文标题:网易云信 即时聊天

          本文链接:https://www.haomeiwen.com/subject/tvyclktx.html