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

前言

上次说了下简单的框架构架,主要是解释了下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/v2/message/regid

参考文档

下面是发送代码:

@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://github.com/idisfkj/HightCopyWX

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,391评论 25 707
  • 微信5.0公众账号运营策略 前言 微信 5.0上线以后,企业公众账号被列入服务号范畴,每月仅可推送一条 信息。基于...
    达芬奇阅读 13,473评论 1 16
  • 罗辑思维,刚开始人们以为他是说书的,后来以为是做公众号的,后来做商城后认为是做知识电商的,现在罗胖说自己是做知识服...
    部落10阅读 3,071评论 0 1
  • 如果我是收藏家,我想收藏什么?画完第一张之后,我发现我跑题了,于是又另画了一张导图。 小时候没有什么爱好,唯一的兴...
    Rosy_1314阅读 535评论 0 0