1. 程式人生 > >極光推送詳細介紹

極光推送詳細介紹

一、極光推送介紹

說起推送,不得不提到極光,高效,穩定,最重要的是免費(使用者量不是非常大的情況下),讓它在推送界佔據了很高地位,如果沒有完全沒有用過的話,還是要花點時間去研究一下,或者遇到一些問題,下面我詳細地一步一步來介紹它,廢話不多說,一起操練起來吧。

二、使用

1.整合

極光的文件整合這塊還是很詳細的,有自動整合和手動整合兩種 ,推薦自動整合,除非你有特殊的癖好

確認android studio的 Project 根目錄的主 gradle 中配置了jcenter支援。(新建project預設配置就支援)

buildscript {
    repositories {
        jcenter()
    }
    ......
}

allprojets {
    repositories {
        jcenter()
    }
}

AndroidManifest的替換變數。

android {
    ......
    defaultConfig {
        applicationId "com.xxx.xxx" //應用的applicationId,極光說是包名,但應該是applicationId更嚴謹一下,可以和包名不一致
        ......

        ndk {
            //選擇要新增的對應cpu型別的.so庫。
            abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'  //一般這幾個就行了,畢竟Android手機基本都是arm
            // 還可以新增 'x86', 'x86_64', 'mips', 'mips64'
        }

        manifestPlaceholders = [
            JPUSH_PKGNAME : applicationId,  //
注意這裡不是讓你替換成你的applicationId,不要動 JPUSH_APPKEY : "你的appkey", //JPush上註冊的包名對應的appkey. JPUSH_CHANNEL : "developer-default", //暫時填寫預設值即可. ] ...... } ...... }

在 module 的 gradle 中新增依賴

dependencies { ...... compile 'cn.jiguang.sdk:jpush:3.0.9' // 此處以JPush 3.0.9 版本為例。 compile 'cn.jiguang.sdk:jcore:1.1.7' // 此處以JCore 1.1.7 版本為例。 ...... }

 : 如果在新增以上 abiFilter 配置之後android Studio出現以下提示:

    NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin

則在 Project 根目錄的gradle.properties檔案中新增:

    android.useDeprecatedNdk=true

注意在使用前要在Application中呼叫JpushInterface.init(this);進行初始化

三、配置別名和標籤

別名(Alias),一個使用者只能設定一個,String型別

標籤(Tag),一個使用者可以設定多個,Set<String>型別

不一定都要設定,可以根據自己需要只設置某一項,或者都設定

從3.0.7開始別名,標籤的設定方法發生了變化,這裡只介紹新的,推薦新的方法,比老方法更好。可以下載官方的Demo看一下,官方的Demo中有一個TagAliasOperatorHelper類,這個是設定的核心類。

下面的方法是核心方法
public void handleAction(Context context,int sequence, TagAliasBean tagAliasBean){
        init(context);
        if(tagAliasBean == null){
            Logger.w(TAG,"tagAliasBean was null");
            return;
        }
        put(sequence,tagAliasBean);
        if(tagAliasBean.isAliasAction){
            switch (tagAliasBean.action){
                case ACTION_GET:
                    JPushInterface.getAlias(context,sequence);
                    break;
                case ACTION_DELETE:
                    JPushInterface.deleteAlias(context,sequence);
                    break;
                case ACTION_SET:
                    JPushInterface.setAlias(context,sequence,tagAliasBean.alias);
                    break;
                default:
                    Logger.w(TAG,"unsupport alias action type");
                    return;
            }
        }else {
            switch (tagAliasBean.action) {
                case ACTION_ADD:
                    JPushInterface.addTags(context, sequence, tagAliasBean.tags);
                    break;
                case ACTION_SET:
                    JPushInterface.setTags(context, sequence, tagAliasBean.tags);
                    break;
                case ACTION_DELETE:
                    JPushInterface.deleteTags(context, sequence, tagAliasBean.tags);
                    break;
                case ACTION_CHECK:
                    //一次只能check一個tag
                    String tag = (String)tagAliasBean.tags.toArray()[0];
                    JPushInterface.checkTagBindState(context,sequence,tag);
                    break;
                case ACTION_GET:
                    JPushInterface.getAllTags(context, sequence);
                    break;
                case ACTION_CLEAN:
                    JPushInterface.cleanTags(context, sequence);
                    break;
                default:
                    Logger.w(TAG,"unsupport tag action type");
                    return;
            }
        }
  }

這個方法封裝了Alias和Tag的所有操作,當然也可以自己封裝,三個引數,第一個,context是Applicaiton的上下文(因為我的ApplicationContext可以在Application中直接取到,所以去掉了這個引數),第二個,sequence 代表一個序號,這個是和老方法的主要區別,目的是區分設定的序號,本類靜態成員變數,需要注意的是在呼叫之前一定要先把它+1,不然會有問題。第三個引數tagAliasBean是一個自定義的類,裡面有放了設定的主要資訊。

handleAction方法以tagAliasBean中的isAliasAction來區分是操作Alias的還是操作Tag的,true為Alias,false為Tag。

具體的操作是設定,刪除還是別的,以tagAliasBean中的action來區分,action的值在類中有定義。前面的一切都是鋪墊,甚至可以不用Demo的方法,自己封裝方法來控制sequence的變化即可,下面的方法才是真正的開始設定,以設定Alias為例

JPushInterface.setAlias(context,sequence,tagAliasBean.alias);

設定了之後如何檢視操作是否成功呢?下面看一下回調方法,首先用一個類如MyJpushMessageReceiver繼承JpushMessageReceiver類,然後在清單檔案中按照要求配置一下,並在類中實現回撥方法

<receiver android:name=".infrastructure.listener.MyJpushMessageReceiver">
<intent-filter>
            <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
            <category android:name="com.bravolinks.wemeeting.wemeetingcustomer_test"/>
        </intent-filter>
 </receiver>
 /**
     * 設定標籤回撥
     * @param jPushMessage
     */
    public void onTagOperatorResult(Context context, JPushMessage jPushMessage) {
        TagAliasHelper.getInstance().onTagOperatorResult(jPushMessage);
        super.onTagOperatorResult(context,jPushMessage);
    }


    /**
     * 設定別名回撥
     * @param jPushMessage
     */
    public void onAliasOperatorResult(Context context,JPushMessage jPushMessage) {
        TagAliasHelper.getInstance().onAliasOperatorResult(jPushMessage);
        super.onAliasOperatorResult(context,jPushMessage);
    }


    /**
     * 檢查Tag設定
     * @param context
     * @param jPushMessage
     */
    public void onCheckTagOperatorResult(Context context,JPushMessage jPushMessage){
        TagAliasHelper.getInstance().onCheckTagOperatorResult(context,jPushMessage);
        super.onCheckTagOperatorResult(context,jPushMessage);
    }

 之所以得到回撥結果中要把結果調回TagAliasOperatorHepler中,是因為如果設定失敗的話,還要再進行處理,下面看一下TagAliasOperatorHepler中的回撥方法。以Alias為例

public void onAliasOperatorResult(Context context, JPushMessage jPushMessage) {
        int sequence = jPushMessage.getSequence();
        Logger.i(TAG,"action - onAliasOperatorResult, sequence:"+sequence+",alias:"+jPushMessage.getAlias());
        init(context);
        //根據sequence從之前操作快取中獲取快取記錄
        TagAliasBean tagAliasBean = tagAliasActionCache.get(sequence);
        if(tagAliasBean == null){
            ExampleUtil.showToast("獲取快取記錄失敗", context);
            return;
        }
        if(jPushMessage.getErrorCode() == 0){
            Logger.i(TAG,"action - modify alias Success,sequence:"+sequence);
            tagAliasActionCache.remove(sequence);
            String logs = getActionStr(tagAliasBean.action)+" alias success";
            Logger.i(TAG,logs);
            ExampleUtil.showToast(logs, context);
        }else{
            String logs = "Failed to " + getActionStr(tagAliasBean.action)+" alias, errorCode:" + jPushMessage.getErrorCode();
            Logger.e(TAG, logs);
            if(!RetryActionIfNeeded(jPushMessage.getErrorCode(),tagAliasBean)) {
                ExampleUtil.showToast(logs, context);
            }
        }
    }

  jPushMessage.getErrorCode() == 0代表設定成功,設定成功的話移除掉之前儲存的設定資訊,這就是要在呼叫handleAction前,把sequecen+1的原因,如果同時設定Alias和Tag,因為sequece是相同的,先設定成功的一個會把儲存的資訊remove掉,後面設定回撥的方法裡就取不到了。

如果因為網路原因設定失敗的話(返回的錯誤碼為6002 超時,6014 伺服器繁忙,都建議延遲重試),可以利用Hander再次設定。可以參考下面的方法

private boolean RetryActionIfNeeded(int errorCode,TagAliasBean tagAliasBean){
        if(!ExampleUtil.isConnected(context)){
            Logger.w(TAG,"no network");
            return false;
        }
        //返回的錯誤碼為6002 超時,6014 伺服器繁忙,都建議延遲重試
        if(errorCode == 6002 || errorCode == 6014){
            Logger.d(TAG,"need retry");
            if(tagAliasBean!=null){
                Message message = new Message();
                message.what = DELAY_SEND_ACTION;
                message.obj = tagAliasBean;
                delaySendHandler.sendMessageDelayed(message,1000*60);
                String logs =getRetryStr(tagAliasBean.isAliasAction, tagAliasBean.action,errorCode);
                ExampleUtil.showToast(logs, context);
                return true;
            }
        }
        return false;
    }
private Handler delaySendHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case DELAY_SEND_ACTION:
                    if(msg.obj !=null && msg.obj instanceof  TagAliasBean){
                        Logger.i(TAG,"on delay time");
                        sequence++;
                        TagAliasBean tagAliasBean = (TagAliasBean) msg.obj;
                        tagAliasActionCache.put(sequence, tagAliasBean);
                        if(context!=null) {
                            handleAction(context, sequence, tagAliasBean);
                        }else{
                            Logger.e(TAG,"#unexcepted - context was null");
                        }
                    }else{
                        Logger.w(TAG,"#unexcepted - msg obj was incorrect");
                    }
                    break;
            }
        }
    };
注:Alias和Tag是不用每次啟動App都要設定的,可以用SharePreference來標記是否設定成功。記得使用者退出登入的時候呼叫清除

Alias和Tag的方法,並把SharePreference的值改變。

Alias和Tag設定成功要怎麼接收訊息呢,極光推送分為通知和自定義訊息,通知的話是預設有通知欄且不可取消,自定義訊息可以自己寫通知欄,因為專案中使用的是通知,這裡只介紹通知。用一個類如JpushReceiver繼承BroadcastRecevier並實現onReceive方法,在清單檔案中按要求配置,如下

        <receiver
            android:name=".infrastructure.listener.JPushReceiver"
            android:enabled="true"
            android:exported="false">
            <intent-filter>
                <action android:name="cn.jpush.android.intent.REGISTRATION" /> <!--Required  使用者註冊SDK的intent-->
                <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" /> <!--Required  使用者接收SDK訊息的intent-->
                <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" /> <!--Required  使用者接收SDK通知欄資訊的intent-->
                <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" /> <!--Required  使用者開啟自定義通知欄的intent-->
                <action android:name="cn.jpush.android.intent.CONNECTION" /><!-- 接收網路變化 連線/斷開 since 1.6.3 -->
                <category android:name="你的applicationId" />
            </intent-filter>
        </receiver>
下面接收的方法中就可以進行處理了
  @Override
public void onReceive(Context context, Intent intentReceive) {
        String action = intentReceive.getAction();
        Bundle bundle = intentReceive.getExtras();
        //-------------------------------接收到通知-------------------------------
        if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(action)) {
            String extra = bundle.getString(JPushInterface.EXTRA_EXTRA);
            String alert = bundle.getString(JPushInterface.EXTRA_ALERT);

            //----------------------------點選了通知------------------------------------
        } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(action)) {
            String extra = bundle.getString(JPushInterface.EXTRA_EXTRA);
           
        }
    }

四、其他說明

設定好Alias和Tag,可以利用極光後臺進行傳送通知的測試,來看是否能夠接收到通知。

所有的推送記錄都能夠在極光後臺中查詢到(後臺推送的要切換成api檢視),如果推送有問題,可以去後臺看看推送記錄,再分析具體是哪個環節出現了問題。

如有錯誤或者任何問題,可以跟我回復,希望大家都能用的順利,愉快,哈哈哈