使用環(huán)信3.xSDK集成小米推送實現(xiàn)消息以及通話時的離線通知

項目源碼:lzan13 / VMChatDemoCall

前言

集成聊天,目的無非就是為了讓兩個人能夠方便的溝通,但是有時我們會退到后臺,kill 程序,這時候別人再發(fā)送消息就收不到了,以及有些用戶還想在呼叫通話時也能通知對方,打開 app 接聽通話,這些都因為 app 被殺死而實現(xiàn)不了;還好有推送服務(wù)可用,蘋果有apns,雖然Androidgcm, 但是在國內(nèi)也用不了,因此就催生了各種各樣的第三方推送,環(huán)信這邊根據(jù)市場設(shè)備情況,選擇了兩家推送集成,在國內(nèi)可以集成小米和華為推送,這樣可以保證在他們自家的設(shè)備上實現(xiàn)離線消息通知;

PS:為什么不用極光,因為極光并不是國內(nèi)那些 rom 廠商自家的推送服務(wù),他們不允許第三方的服務(wù)器在自家設(shè)備的后臺撒歡
PS:經(jīng)測試小米的多報名在推送上不好使,不知道現(xiàn)在怎么樣,如果有使用多包名測試不行的情況,可以重新創(chuàng)建應(yīng)用試下

廢話不多說,今天就通過集成最新的小米推送來實現(xiàn)下消息的離線推送通知,以及被呼叫方離線時方推送提醒對方啟動 app 接聽通話;其實都是通過集成推送完成!

準(zhǔn)備工作

首先你的項目需要集成環(huán)信 sdk,并且已經(jīng)實現(xiàn)了發(fā)送消息以及音視頻通話功能(這個可以直接用我上邊 github 上的項目);
然后你需要有小米的開發(fā)者賬戶,需要創(chuàng)建一個應(yīng)用,包名要和你自己的項目一樣,然后需要用到的就是應(yīng)用的appId、appKeyappSecret,這些在環(huán)信開發(fā)者后臺上傳小米證書,以及在項目中初始化小米推送需要用到;

開始集成

首先這邊先把證書弄好了,證書的名字和秘鑰以及包名一定要對應(yīng):


QQ20170505-162024.png

然后需要做的就是在代碼中集成小米推送,需要做的有兩個地方:

  1. 在初始化 sdk 的時候調(diào)用 options 設(shè)置小米的 appId 和 appKey
  2. 在 AndroidManifest配置文件配置相應(yīng)的權(quán)限和廣播接收器以及服務(wù)
    /**
     * 初始化環(huán)信sdk,并做一些注冊監(jiān)聽的操作,這里把其他的處理都去掉了只寫了小米推送
     */
    private void initHyphenate() {
        // 初始化sdk的一些配置
        EMOptions options = new EMOptions();
        // 設(shè)置小米推送 appID 和 appKey
        options.setMipushConfig("2882303761517573806", "5981757315806");
        // 初始化環(huán)信SDK,一定要先調(diào)用init()
        EMClient.getInstance().init(context, options);
        // 開啟 debug 模式
        EMClient.getInstance().setDebugMode(true);
    }

然后就是AndroidManifest配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.vmloft.develop.app.demo.call">

    <!-- 項目權(quán)限配置 -->
    <!--小米推送相關(guān)權(quán)限-->
    <permission
        android:name="com.vmloft.develop.app.demo.call.permission.MIPUSH_RECEIVE"
        android:protectionLevel="signature"/>
    <uses-permission android:name="com.vmloft.develop.app.demo.call.permission.MIPUSH_RECEIVE"/>
    <!--小米推送權(quán)限 end-->
    <!--程序入口-->
    <application
        android:name="com.vmloft.develop.app.demo.call.AppApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
        <!--小米推送相關(guān)配置-->
        <service
            android:name="com.xiaomi.push.service.XMJobService"
            android:enabled="true"
            android:exported="false"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:process=":pushservice"/>

        <service
            android:name="com.xiaomi.push.service.XMPushService"
            android:enabled="true"
            android:process=":pushservice"/>

        <service
            android:name="com.xiaomi.mipush.sdk.PushMessageHandler"
            android:enabled="true"
            android:exported="true"/>
        <service
            android:name="com.xiaomi.mipush.sdk.MessageHandleService"
            android:enabled="true"/>

        <!--推送消息廣播接收器,這個廣播接收器必須繼承自環(huán)信實現(xiàn)的接收器-->
        <receiver
            android:name=".push.MIPushReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE"/>
            </intent-filter>
            <intent-filter>
                <action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED"/>
            </intent-filter>
            <intent-filter>
                <action android:name="com.xiaomi.mipush.ERROR"/>
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.xiaomi.push.service.receivers.PingReceiver"
            android:exported="false"
            android:process=":pushservice">
            <intent-filter>
                <action android:name="com.xiaomi.push.PING_TIMER"/>
            </intent-filter>
        </receiver>
        <!--小米推送配置 end-->
    </application>
</manifest>

其中MIPushReceiver這個廣播接收器可以不用自己實現(xiàn),如果自己實現(xiàn),必須繼承自環(huán)信 sdk 實現(xiàn)的廣播接收器EMMipushReceiver實現(xiàn),也可以直接用(這里如果需要自己與自己的業(yè)務(wù)處理可以繼承環(huán)信實現(xiàn)的的這個廣播接收器,不然收不到離線推送,然后去處理自己的邏輯;詳細(xì)可以根據(jù)小米推送官方 sdk 文檔進(jìn)行了解下);

當(dāng)我們做完這些之后在收到離線消息后就可以收到推送通知了,只不過這個推送通知我們不能自定義,因為這些都是服務(wù)器推什么我們接受什么,這點比較坑!

通話的離線通知

上邊已經(jīng)實現(xiàn)了消息的離線通知,我們下邊就要做當(dāng)呼叫對方時,對方卻不在線,我們怎么通知對方打開 app 進(jìn)行接聽呢?
曾經(jīng)集成過環(huán)信用戶應(yīng)該知道,在呼叫對方不在線后會馬上結(jié)束通話,回調(diào)對方不在線,在新版3.2.2的 sdk 中新增設(shè)置音視頻參數(shù)及呼叫時對方離線是否發(fā)推送的接口,在初始化的時候進(jìn)行以下設(shè)置:

// 設(shè)置通話過程中對方如果離線是否發(fā)送離線推送通知,默認(rèn) false
EMClient.getInstance().callManager().getCallOptions().setIsSendPushIfOffline(true);
// 設(shè)置了這個之后就不會在通話狀態(tài)監(jiān)聽中回調(diào)對方不在線,需要實現(xiàn)另外一個回調(diào)
...
// 設(shè)置音頻通話推送提供者,在 onRemoteOffline()回調(diào)中給對方發(fā)送消息就行了
EMClient.getInstance().callManager().setPushProvider(EMCallManager.EMCallPushProvider {
    @Override public void onRemoteOffline(String username) {
        EMMessage message = EMMessage.createTxtSendMessage("有人呼叫你,開啟 APP 接聽吧", username);
        // 設(shè)置強制推送
        message.setAttribute("em_force_notification", "true");
        // 設(shè)置自定義推送提示
        JSONObject extObj = new JSONObject();
        try {
            extObj.put("em_push_title", "有人呼叫你,開啟 APP 接聽吧");
            extObj.put("extern", "定義推送擴展內(nèi)容");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        message.setAttribute("em_apns_ext", extObj);
        message.setMessageStatusCallback(new EMCallBack() {
            @Override public void onSuccess() {
              // 在這里可以刪除消息
            }
            @Override public void onError(int i, String s) {
              // 在這里可以刪除消息
            }
            @Override public void onProgress(int i, String s) {}
        });
        EMClient.getInstance().chatManager().sendMessage(message);
    }
});

實現(xiàn)了上邊的這個推送提供者之后,當(dāng)對方不在線就會回調(diào) onRemoteOffline()方法,就可以發(fā)送一條消息給對方,然后上邊我們已經(jīng)集成了小米推送,就可以通過離線推送的方式通知對方有新消息,對方看到后點擊通知欄就可以打開 app了,這個時候我們的語音或視頻呼叫還在一直呼叫,然后就可以連通了!

結(jié)語

OK 到這里基本就已經(jīng)完成了,大家可以運行自己的項目,或者我上邊的 demo 測試下,我這邊通過小米5測試 OK;其實集成推送部分并不難,只是有幾點需要注意:

  • 環(huán)信開發(fā)者后臺的推送證書設(shè)置時一定要注意應(yīng)用包名和小米推送后臺的應(yīng)用包名以及自己項目的包名,三個地方一定要一致
  • 初始化設(shè)置一定要通過環(huán)信的 options 去設(shè)置小米推送的 appId 和 appKey,不需要用小米的注冊方法自己注冊;
  • Androidmanifest 一定要加上環(huán)信的廣播接收器,或者繼承自環(huán)信封裝的廣播接收器

注意以上幾點基本推送就沒有問題了,如果不行可以先通過小米開發(fā)者后臺的推送工具測試推送是否通了,然后檢查以上幾點;

PS:華為推送相關(guān)其實一樣,不過因為華為不允許個人開發(fā)者注冊賬戶,所以這里暫時不贅述

參考資料

小米推送Android SDK文檔
環(huán)信推送相關(guān)文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 最近一段時間工作量比較大, 抽不出時間來整理博客, 趁今天任務(wù)量較小的時候整理下關(guān)于環(huán)信推送的問題, 介紹. 集成...
    imGeek閱讀 2,834評論 1 3
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,675評論 25 709
  • 點擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個完善的 IM 系統(tǒng)...
    layjoy閱讀 14,273評論 0 15
  • 極光推送: 1.JPush當(dāng)前版本是1.8.2,其SDK的開發(fā)除了正常的功能完善和擴展外也緊隨蘋果官方的步伐,SD...
    Isspace閱讀 6,867評論 10 16
  • 介紹查爾斯.狄更斯的小說《圣誕歡歌》。 一、故事簡介與文學(xué)價值 1、主要故事情節(jié) 富有而冷漠無情的、自私透頂?shù)牧邌?..
    爺有蔓草閱讀 868評論 0 0

友情鏈接更多精彩內(nèi)容