Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發筆記(一百零四)消息推送SDK

Android開發筆記(一百零四)消息推送SDK

編輯:關於Android編程

推送的集成

常用概念

推送:從服務器把消息實時發到客戶端app上,這就是推送,推送可用於發送系統通知、發送推薦信息、發送聊天消息等等。
別名:用於給移動設備取個好記的名字,比如電腦有計算機名,可以把別名理解為開發者給移送設備起的外號。不過,多個移動設備可以起一樣的別名,這幾個設備就會同時收到發給該別名的消息。
標記:用於給移動設備打標簽,可以理解為分類,比如超市裡的泰國大米既可以打上“糧食制品”的標簽,也可以打上“進口商品”的標簽。服務器可以統一給某個種類的移動設備發送消息;如果移動設備打上本設備手機號碼的標簽,那麼服務器就能該號碼的手機單獨發消息。
自定義消息:推送的消息內容一般由sdk直接展示在系統的通知欄,不過有時候我們希望由自己控制展示通知的時機,比如說要預先處理某項事務,或者說以對話框形式展現消息等等,在這些時候,自定義消息就派上用場了,app可以先接收服務器發來的自定義消息,然後自主選擇接下來的處理邏輯。


集成步驟

推送sdk都分為客戶端與服務端兩塊,開發者在客戶端app上集成客戶端sdk,還得在服務器的程序上集成服務端sdk。不過推送客戶端與服務端sdk並不直接通信,它們之間必須通過推送廠商的推送服務器來中轉。下面是推送sdk集成時的數據流轉過程:
1、集成了客戶端sdk的app啟動之後,要先進行初始化(注冊)操作,即客戶端sdk向推送服務器(推送廠商)發送初始化請求(包含appkey、master secret),推送服務器給該移動設備分配一個唯一標識。
2、客戶端sdk向推送服務器發送別名與標記設置,推送服務器給該移動設備登記相應的別名與標記。
3、客戶端sdk向推送服務器發送開啟推送請求,推送服務器表示知道了,接下來如果有消息就會告訴你。
4、服務端sdk封裝消息推送請求,包括appkey、master secret、別名、標記、推送內容等等信息。
5、服務端sdk向推送服務器發送消息推送請求,推送服務器首先校驗appkey和master secret是否合法;校驗通過,再根據別名和標記挑出需要接收通知的客戶端設備集合;最後把推送內容分別推送到符合條件的客戶端設備上。


極光推送

極光推送是使用量較大的一個推送sdk,支持ios、android、winphone等平台。極光推送的客戶端sdk包為jpush-android-2.1.5.jar,服務端sdk包為jpush-client-3.2.9.jar,服務端的sdk還依賴於gson、slf4j、log4j等jar包。


推送調用的接口

在APP上啟用極光推送,用到的是JPushInterface類,下面是JPushInterface的常用方法說明:
init : 初始化。可在MainApplication或者MainActivity中調用。
stopPush : 暫停接收通知。
resumePush : 恢復接收通知。
isPushStopped : 判斷推送是否停止
getRegistrationID : 獲取注冊id。
setAliasAndTags : 設置本設備的別名與標記。如果服務器指定向某個手機號碼推送消息,則app調用該方法把手機號碼設置為別名或標記。
setAlias : 設置別名。
setTags : 設置標記。
clearAllNotifications : 清除所有通知。
setPushNotificationBuilder : 設置通知欄樣式。類型為1表示使用基本樣式,為2表示使用自定義樣式。
setPushTime : 設置接收通知的時間段。可設置周一到周日,每天的起始時間與結束時間。


推送事件的廣播

極光推送的各事件都是靠廣播發出來,並不使用監聽器,所以我們要在app中自定義廣播接收器來處理事件。下面是極光推送幾個常用的事件介紹:
1、JPushInterface.ACTION_REGISTRATION_ID
表示注冊SDK的事件,對應的intent-filter是
2、JPushInterface.ACTION_MESSAGE_RECEIVED
表示接收自定義消息的事件,對應的intent-filter是
3、JPushInterface.ACTION_NOTIFICATION_RECEIVED
表示接收通知的事件,對應的intent-filter是
4、JPushInterface.ACTION_NOTIFICATION_OPENED
表示點擊通知欄的事件,對應的intent-filter是
5、JPushInterface.ACTION_RICHPUSH_CALLBACK
表示接收富文本(如網頁、多媒體等等)回調的事件,對應的intent-filter是
6、JPushInterface.ACTION_CONNECTION_CHANGE
表示網絡連接變化(連上、斷開)的事件,對應的intent-filter是


下面是在AndroidManifest.xml注冊極光廣播接收器的xml例子:
    <receiver android:enabled="true" android:exported="false" android:name=".JpushReceiver">
        <intent-filter>
            <action android:name="cn.jpush.android.intent.REGISTRATION">
            <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED">
            <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED">
            <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED">
            <action android:name="cn.jpush.android.intent.ACTION_RICHPUSH_CALLBACK">
            <action android:name="cn.jpush.android.intent.CONNECTION">
            <category android:name="com.example.exmpushjpush">
        </category></action></action></action></action></action></action></intent-filter>
    </receiver>


服務器發送通知

APP代碼實現了客戶端接收推送的功能,接下來還得服務器配合,服務器的程序發出推送消息,客戶端app接收消息。
下面是服務器發送消息的具體步驟:
1、構造一個JPushClient對象,該對象包含以下信息:AppKey、Master Secret、重試次數與超時時間等參數。
2、按照參數分別生成Platform平台對象、Audience受眾對象、Notification通知對象、Message自定義消息對象。
3、根據第二步產生的各對象,構建PushPayload對象。
4、調用JPushClient對象的sendPush方法,把PushPayload對象信息發送出去。
5、sendPush方法調用失敗則拋出異常,調用成功則返回PushResult結果對象,裡面包含本次發送的消息編號。


上面步驟三的PushPayload對象是整個發送過程的關鍵,該對象的構建采用建造者模式,由PushPayload.Builder對各參數進行設置,說明如下:
setPlatform : 設置消息接收平台。主要有三種類型,分別是:Platform.ios()、Platform.android()、Platform.winphone()。
setAudience : 設置消息接受群體。主要有三種受眾,Audience.all()表示所有用戶,Audience.alias(alias)表示指定別名的用戶,Audience.tag(tag)表示指定標記的用戶。
setNotification : 設置通知內容。根據不同平台有三種設置方法,分別是:Notification.ios、Notification.android、Notification.winphone。
setMessage : 設置自定義消息。注意,只有android和winphone可以設置自定義消息,ios只能設置通知。
build : 根據設置內容構建PushPayload對象。


下面是服務器發送通知的代碼示例:
import cn.jpush.api.JPushClient;
import cn.jpush.api.common.ClientConfig;
import cn.jpush.api.common.resp.APIConnectionException;
import cn.jpush.api.common.resp.APIRequestException;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.Notification;
import java.util.Map;
import java.util.Set;

public class MessagePush {
	public static long IOS = 0L;
	public static long Android = 1L;

	private String mTitle;
	private String mMessage;
	private long mPlatformType;
	
	private JPushClient mJpushClient;
	private Platform mPlatform;
	private Audience mAudience;
	private Notification mNotify;
	private Message mMsg;
	public long mMsgId;
	public String mStatus;
	public String mErrCode;
	public String mErrMsg;

	public MessagePush(String appKey, String masterSecret, String message) {
		ClientConfig conf = ClientConfig.getInstance();
		conf.setMaxRetryTimes(3);
		mJpushClient = new JPushClient(masterSecret, appKey, null, conf);

		mMessage = message;
		mTitle = "";
		mPlatform = Platform.all();
		mMsg = Message.content(message);
		mAudience = Audience.all();
		setMsg(-1L, 0, 0, "");
	}

	public MessagePush(String appKey, String masterSecret, String message, String title) {
		this(appKey, masterSecret, message);
		mTitle = title;
	}

	public MessagePush(String appKey, String masterSecret, String message,
			String title, Long platformType, Map extras) {
		this(appKey, masterSecret, message, title);
		mPlatformType = platformType.longValue();
		System.out.println("MessagePush platformType=" + platformType);
		if (platformType.longValue() == IOS) {
			mPlatform = Platform.ios();
			mNotify = Notification.ios(mMessage, extras);
		} else if (platformType.longValue() == Android) {
			mPlatform = Platform.android();
			mNotify = Notification.android(mMessage, mTitle, extras);
		} else {
			mPlatform = Platform.winphone();
			mNotify = Notification.winphone(mMessage, extras);
		}
	}

	public void setAlias(Set alias) {
		mAudience = Audience.alias(alias);
	}

	public void setTag(String[] tag) {
		mAudience = Audience.tag(tag);
	}

	public void sendPush() {
		PushPayload payload = build();
		try {
			PushResult result = mJpushClient.sendPush(payload);
			mMsgId = result.msg_id;
			System.out.println("Got result - " + result);
		} catch (APIConnectionException e) {
			System.out.println("Connection error. Should retry later. "
					+ e.getMessage());
			setMsg(-1L, -1, -1, e.getMessage());
		} catch (APIRequestException e) {
			System.out.println("HTTP Status: " + e.getStatus());
			System.out.println("Error Code: " + e.getErrorCode());
			System.out.println("Error Message: " + e.getErrorMessage());
			System.out.println("Msg ID: " + e.getMsgId());
			setMsg(e.getMsgId(), e.getStatus(), e.getErrorCode(),
					e.getErrorMessage());
		}
	}

	private void setMsg(long msgId, int status, int errCode, String errMsg) {
		mMsgId = msgId;
		mStatus = String.valueOf(status);
		mErrCode = String.valueOf(errCode);
		mErrMsg = errMsg;
	}

	private PushPayload build() {
		System.out.println("build platformType=" + mPlatformType);
		PushPayload push;
		if (mPlatformType == IOS) {
			push = PushPayload.newBuilder().setPlatform(mPlatform)
					.setAudience(mAudience).setNotification(mNotify)
					.build();
		} else if (mPlatformType == Android) {
			push = PushPayload.newBuilder().setPlatform(mPlatform)
					.setAudience(mAudience).setMessage(mMsg).build();
					//.setAudience(mAudience).setNotification(mNotify).build();
		} else {
			push = PushPayload.newBuilder().setPlatform(mPlatform)
					.setAudience(mAudience).setMessage(mMsg).build();
		}
		return push;
	}
}


個推

個推是另一個使用較多的推送sdk,它支持ios和android,但不支持winphone,不過服務器除了java,還支持PHP、Python、C++、C#等等。個推的客戶端sdk包為GetuiSDK2.8.1.0.jar和GetuiExt-2.0.3.jar,服務端sdk包為gexin-rp-sdk-base-4.0.0.7.jar、gexin-rp-sdk-http-4.0.1.2.jar和gexin-rp-sdk-template-4.0.0.4.jar,服務端的sdk還依賴於commons、jackson、protobuf等jar包。


推送調用的接口

在APP上啟用個推,用到的是PushManager類,下面是PushManager的常用方法說明:
getInstance : 獲得PushManager的單例。
initialize : 初始化。
turnOnPush : 開啟推送。
turnOffPush : 關閉推送。
isPushTurnedOn : 判斷推送是否開啟。
getClientid : 獲取客戶端id。
setTag : 設置標簽。
bindAlias : 綁定別名。
unBindAlias : 解綁別名。
setSilentTime : 設置靜默時間段。即從幾點到幾點不接收通知。


推送事件的廣播

個推也使用廣播來發送事件,不過不像極光那樣細分了許多事件,也需要自定義廣播接收器。下面是個推幾個常用的事件介紹:
事件類型根據bundle.getInt(PushConsts.CMD_ACTION)來區分
1、PushConsts.GET_CLIENTID : 獲得客戶端id。其實就是注冊,相當於極光的JPushInterface.ACTION_REGISTRATION_ID
2、PushConsts.GET_MSG_DATA : 收到自定義消息。相當於極光的JPushInterface.ACTION_MESSAGE_RECEIVED


下面是在AndroidManifest.xml注冊個推廣播接收器的xml例子:
        
            
                
            
        


服務器發送通知

下面是服務器發送消息的具體步驟:
1、構造IGtPush對象,該對象包含以下信息:個推服務器地址、AppKey、Master Secret。
2、按照參數分別生成Template模板對象、AppConditions條件對象、AppID隊列等等。
3、根據第二步產生的各對象,構建AppMessage對象。
4、調用IGtPush對象的pushMessageToApp方法,把AppMessage對象信息發送出去。
5、pushMessageToApp方法調用失敗則拋出異常,調用成功則返回IPushResult結果對象,裡面包含本次發送的結果信息。


上面步驟三的AppMessage對象是整個發送過程的關鍵,該對象的常用方法說明如下:
setAppIdList : 設置AppID隊列。即往綁定哪些AppID的用戶發送消息。
setConditions : 設置條件信息。包括手機類型、區域、標簽等等。
setData : 設置模板數據。模板Template定義了消息的具體樣式,下面是個推包裝好的幾個常用模板:
--NotificationTemplate : 通知模板。自動在通知欄裡顯示消息,點擊後跳到app首頁。該模板相當於極光的Notification。
--TransmissionTemplate : 透傳模板。不會自動展示通知欄,由開發者在廣播接收器的PushConsts.GET_MSG_DATA分支中自行處理。該模板相當於極光的Message。
--LinkTemplate : 鏈接模板。自動在通知欄裡顯示消息,點擊後跳轉到指定URL。
--NotyPopLoadTemplate : 下載提示模板。自動在通知欄裡顯示消息,點擊後下載指定安裝包。


下面是服務器發送通知的代碼示例:
import java.util.ArrayList;
import java.util.List;

import com.gexin.rp.sdk.base.IPushResult;
import com.gexin.rp.sdk.base.impl.AppMessage;
import com.gexin.rp.sdk.base.uitls.AppConditions;
import com.gexin.rp.sdk.http.IGtPush;
import com.gexin.rp.sdk.template.NotificationTemplate;

public class PushtoAppNotify {
    //采用"Java SDK 快速入門", "第二步 獲取訪問憑證 "中獲得的應用配置,用戶可以自行替換
	private static String appId = "FJ9uNM6WkS8laiS3C05W9";
    private static String appKey = "cpV7gRK6IlAo26aDZGMtI1";
    private static String masterSecret = "QSvOwGnx0E9jEMpiXtqJ39";
	static String host = "http://sdk.open.api.igexin.com/apiex.htm";

    public static void main(String[] args) throws Exception {

        IGtPush push = new IGtPush(host, appKey, masterSecret);

        NotificationTemplate template = NotificationTemplateDemo();
        AppMessage message = new AppMessage();
        message.setData(template);

        message.setOffline(true);
        //離線有效時間,單位為毫秒,可選
        message.setOfflineExpireTime(24 * 1000 * 3600);
        //推送給App的目標用戶需要滿足的條件
        AppConditions cdt = new AppConditions(); 
        List appIdList = new ArrayList();
        appIdList.add(appId);
        message.setAppIdList(appIdList);
        //手機類型
        List phoneTypeList = new ArrayList();
        //省份
        List provinceList = new ArrayList();
        //自定義tag
        List tagList = new ArrayList();

        cdt.addCondition(AppConditions.PHONE_TYPE, phoneTypeList);
        cdt.addCondition(AppConditions.REGION, provinceList);
        cdt.addCondition(AppConditions.TAG,tagList);
        message.setConditions(cdt); 

        IPushResult ret = push.pushMessageToApp(message,"任務別名_toApp");
        System.out.println(ret.getResponse().toString());
    }

    public static NotificationTemplate NotificationTemplateDemo() throws Exception {
        NotificationTemplate template = new NotificationTemplate();
        template.setAppId(appId);
        template.setAppkey(appKey);
        template.setTitle("PushtoAppNotify標題");
        template.setText("PushtoAppNotify內容");
        template.setLogo("icon.png");
        template.setLogoUrl("");
        template.setIsRing(true);
        template.setIsVibrate(true);
        template.setIsClearable(true);
	    // 透傳消息設置,1為強制啟動應用,客戶端接收到消息後就會立即啟動應用;2為等待應用啟動
	    template.setTransmissionType(1);
	    template.setTransmissionContent("PushtoAppNotify請輸入您要透傳的內容");

        return template;
    }
    
    public static class NotificationTemplateDemo {

    	public static NotificationTemplate notificationTemplateDemo(String appId, String appkey) {
    	    NotificationTemplate template = new NotificationTemplate();
    	    // 設置APPID與APPKEY
    	    template.setAppId(appId);
    	    template.setAppkey(appkey);
    	    // 設置通知欄標題與內容
    	    template.setTitle("請輸入通知欄標題");
    	    template.setText("請輸入通知欄內容");
    	    // 配置通知欄圖標
    	    template.setLogo("icon.png");
    	    // 配置通知欄網絡圖標
    	    template.setLogoUrl("");
    	    // 設置通知是否響鈴,震動,或者可清除
    	    template.setIsRing(true);
    	    template.setIsVibrate(true);
    	    template.setIsClearable(true);
    	    // 透傳消息設置,1為強制啟動應用,客戶端接收到消息後就會立即啟動應用;2為等待應用啟動
    	    template.setTransmissionType(1);
    	    template.setTransmissionContent("請輸入您要透傳的內容");
    	    // 設置定時展示時間
    	    // template.setDuration("2015-01-16 11:40:00", "2015-01-16 12:24:00");
    	    return template;
    	}
    	
    }

}


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved