Android高仿微信之mvp实现(二)

485 查看


前言

上次说了下简单的框架构架,主要是解释了下MVP的原理实现。虽然上次的功能没有很多,但主要是把框架搭好,才能更好的进行下面的操作。如果还有不了解的可以先看下我前面的文章:Android高仿微信之mvp实现(一)
好了,这次我们要介绍的是微信聊天界面功能的简单实现。

原理

其实知道了原理你就会发现它是多么的简单。这里没有服务器所以是基于推送实现的,网上也有一些这方面的资料,一般是基于百度云的,我这里是基于小米推送来实现消息的传递。大家都知道现在推送无处不在,如果还没有接触推送的话,还是先去简单的补下功课在来看就能更好的了解下面说的。

要想实现消息的传递,就要有发送与接收功能,首先对于接收so easy 了只要我们在自己的Android应用中集成小米的ISDK(我这里是以小米推送为例的)。就已经实现的接收功能,对于接收我分了两种,一种的正常聊天得信息,而另一种就是我们自己注册时发送的信息。对于第一种消息我们要根据用户设备唯一标识与用户账号来存储下发过来的消息,为以后显示不同用户聊天记录。对于第二中,是在我们使用时必须先注册,一旦注册成功就会向所有的用户发送一条注册信息,该消息包括用户的基本信息与设备标识,只要在信息时间的有效时间之内,注册了得用户就能接收该注册消息。这个是很重要的身份识别,对消息的发送,用户的添加都是重要的标识。说了接收,反过来发送也是一样的分两种,只是旋转一下位置而已。

配置小米SDK

首先进入小米开发平台,为自己的应用开启推送功能,然后下载SDK根据官方文档做好相应的配置,前期就大功告成了。

如果没接触过的只要耐心看文档就没什么问题,文档很详细

接收

前面我已经说了接收是相对来说较简单的了,如果你前面配置好了小米的SDK,那么你就有一个自定义的extends PushMessageReceiver的类,在该类中用各种相应的接收信息方法,对了忘了说消息的发送类型,这里分为两种

  • 通知栏显示的消息

  • 透传消息

通知栏显示的消息不用我多说了,至于透传消息简单点就是不用通知栏显示,直接在内部接收发送过来的消息。

我们聊天使用的当然的透传消息,所以我们可以在下面的方法中接收到透传发送过来的消息对于两种接收消息做相应的处理:

/**
     * 接收服务器发送的透传消息
     *
     * @param context
     * @param message
     */
    @Override
    public void onReceivePassThroughMessage(Context context, MiPushMessage message) {
        mMessage = message.getContent();
        if (!TextUtils.isEmpty(message.getTopic())) {
            mTopic = message.getTopic();
        } else if (!TextUtils.isEmpty(message.getAlias())) {
            mAlias = message.getAlias();
        }
        Intent intent = new Intent();
        //user information
        if (mMessage.indexOf("^") != -1 && mMessage.indexOf("@") != -1) {
            int index1 = mMessage.lastIndexOf("^");
            int index2 = mMessage.lastIndexOf("@");
            String userName = mMessage.substring(0, index1);
            String regId = mMessage.substring(index1 + 1, index2);
            String number = mMessage.substring(index2 + 1);

            RegisterInfo info = new RegisterInfo();
            info.setUserName(userName);
            info.setNumber(number);
            info.setRegId(regId);
            RegisterDataHelper helper = new RegisterDataHelper(App.getAppContext());
            Cursor cursor = helper.query(number, regId);
            if (cursor != null && cursor.getCount() > 0) {
                for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                    if (CursorUtils.formatString(cursor, RegisterDataHelper.RegisterDataInfo.REGID).equals(regId)
                            && CursorUtils.formatString(cursor, RegisterDataHelper.RegisterDataInfo.NUMBER).equals(number)) {
                        if (!CursorUtils.formatString(cursor, RegisterDataHelper.RegisterDataInfo.USER_NAME).equals(userName))
                            // update user information
                            helper.update(info, number, regId);
                        cursor.close();
                        return;
                    }
                }
                cursor.close();
            }
            // insert user information
            helper.insert(info);
            if (SPUtils.getString("regId").equals(App.DEVELOPER_ID)){
                WXDataHelper wxHelper = new WXDataHelper(App.getAppContext());
                WXItemInfo itemInfo = new WXItemInfo();
                itemInfo.setRegId(regId);
                itemInfo.setTitle(userName);
                itemInfo.setNumber(number);
                itemInfo.setContent(String.format(App.HELLO_MESSAGE, userName));
                itemInfo.setCurrentAccount(SPUtils.getString("userPhone"));
                itemInfo.setTime(CalendarUtils.getCurrentDate());
                wxHelper.insert(itemInfo);
            }

        } else {
            // chat information
            int index1 = mMessage.lastIndexOf("(");
            String rMessage = mMessage.substring(0, index1);
            String extraMessage = mMessage.substring(index1 + 1);

            int index2 = extraMessage.indexOf("@");
            int index3 = extraMessage.indexOf("@", index2 + 1);
            String receiverNumber = extraMessage.substring(0, index2);
            String regId = extraMessage.substring(index2 + 1, index3);
            String sendNumber = extraMessage.substring(index3 + 1);

            ChatMessageInfo chatMessageInfo = new ChatMessageInfo();
            chatMessageInfo.setMessage(rMessage);
            chatMessageInfo.setFlag(0);
            chatMessageInfo.setTime(CalendarUtils.getCurrentDate());
            chatMessageInfo.setReceiverNumber(receiverNumber);
            chatMessageInfo.setRegId(regId);
            chatMessageInfo.setSendNumber(sendNumber);

            if (App.mNumber.equals(sendNumber) && App.mRegId.equals(regId)) {
                //在当前聊天界面
                intent.setAction("com.idisfkj.hightcopywx.chat");
                Bundle bundle = new Bundle();
                bundle.putSerializable("chatMessageInfo", chatMessageInfo);
                intent.putExtras(bundle);
                App.getAppContext().sendBroadcast(intent);
            } else {
                //不在当前聊天界面
                ChatMessageDataHelper helper = new ChatMessageDataHelper(App.getAppContext());
                helper.insert(chatMessageInfo);
            }
        }
    }

代码就不解释了,自己研究研究

发送

如果你看了文档的话就应该有点头绪了,发送就是使用HTTP请求向小米所提供的API根据你提供的regIduserAccountaliastopic等发送你要发送的消息内容,我用的是regId API:https://api.xmpush.xiaomi.com...

参考文档

下面是发送代码:

@Override
    public void requestData(final requestListener listener, final String chatContent, final String number, final String regId, final ChatMessageDataHelper helper) {
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, UrlUtils.ChatUrl(chatContent, number, regId)
                , null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject jsonObject) {
                mChatMessageInfo = new ChatMessageInfo();
                mChatMessageInfo.setMessage(chatContent);
                mChatMessageInfo.setFlag(1);
                mChatMessageInfo.setTime(CalendarUtils.getCurrentDate());
                mChatMessageInfo.setReceiverNumber(number);
                mChatMessageInfo.setRegId(regId);
                mChatMessageInfo.setSendNumber(SPUtils.getString("userPhone", ""));
                listener.onSucceed(mChatMessageInfo, helper);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Log.d("TAG", volleyError.getMessage());
                listener.onError(volleyError.getMessage());
            }
        }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap<String, String> header = new HashMap<>();
                header.put("Authorization", "key=" + App.APP_SECRET_KEY);
                return header;
            }
        };
        VolleyUtils.addQueue(jsonObjectRequest, "chatRequest");
    }

由于涉及的代码还是有点多的,这里就不一一展开,有兴趣的可以自己根据后面的地址StarFork下载代码查看。

如果你安装注册了,由于时间原因,目前聊天界面只会自动添加我为好友,你们如果有不懂得可以简单的发消息给我,但不一定都会回。好了,下面看看效果吧

效果

更多:https://idisfkj.github.io
项目地址:https://github.com/idisfkj/Hi...