iOS訊息推送(Java實現)
首先來了解一下蘋果的訊息推送APNS(英文全稱:Apple Push Notification service)
先來看兩張蘋果對於推送的兩張解釋圖:
大概的意思就是,提供商把訊息推送至蘋果的推送伺服器,再由蘋果推送伺服器將訊息推送給手機客戶端,或者反過來手機客戶端把訊息推送至蘋果推送伺服器,再由蘋果推送服務將訊息推送至提供商。這裡提到的提供商可以是像極光推送或其他供應商,亦或是自己的伺服器。
這裡提到了蘋果推送伺服器向手機端推送訊息,那麼它是怎麼知道是推送到哪個手機上的呢,這個就汲及到一個Token的問題。
Token是每臺iOS手機唯一的標識,在啟動手機應用時,會向蘋果推送伺服器去請求得到唯一的Token。當然,雖然每次應用啟動時都會去請求得到Token,但是針對於同一部手機,返回回來的Token值都是一致的。
所以當蘋果推送伺服器只要知道要推送給哪個Token即可知道是推送至哪個手機。
接下來看一下APNS如何去實現訊息的推送
1.首先是要準備好證書
從你的蘋果電腦上匯出CSR檔案,開啟鑰匙串-->鑰匙串訪問-->證書助理-->從證書頒發機構請求證書,然後一路輸入郵件地址和儲存的檔案,儲存到電腦,CSR檔案就生成了。
到蘋果開發者官網http://developer.apple.com,登陸進入到證書管理模組,Identifiers -->
App IDs, 如果你的應用ID還沒有新增進來,那麼點右上角加號新增進來,如果已經加進來了,單擊進入,進麼設定,將Push Notifications
一路設定好,上傳剛才從蘋果電腦上匯出來的CSR檔案,並匯出證書,雙擊匯出的證書,它會自動安裝到蘋果電腦上,安裝好後,在鑰匙串工具中匯出Push證書,即匯出來後是一個P12檔案,P12檔案是用於後邊Java後臺連線APNS使的。
xcode中修改證書為剛才安裝好的推送證書。由於推送需要用到真機,所以還需要Provisioning Profiles 證書,生成後也要在xcode中設定好。
2.給應用註冊推送服務
- 首先在專案的AppDelegate.m中加入以下兩個代理方法
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = [NSString stringWithFormat:@"%@", deviceToken]; //獲取終端裝置標識,這個標識需要通過介面傳送到伺服器端,伺服器端推送訊息到APNS時需要知道終端的標識,APNS通過註冊的終端標識找到終端裝置。 NSLog(@"My token is:%@", token); }
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSString *error_str = [NSString stringWithFormat: @"%@", error];
NSLog(@"Failed to get token, error:%@", error_str);
}
- 在AppDelegate.m的(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中加入註冊訊息通知推送能力;加入當應用程式處於未啟動狀態時,判斷是否由遠端訊息通知觸發;加入清除訊息推送通知標記。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//判斷是否由遠端訊息通知觸發應用程式啟動
if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]!=nil) {
//獲取應用程式訊息通知標記數(即小紅圈中的數字)
int badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
if (badge>0) {
//如果應用程式訊息通知標記數(即小紅圈中的數字)大於0,清除標記。
badge--;
//清除標記。清除小紅圈中數字,小紅圈中數字為0,小紅圈才會消除。
[UIApplication sharedApplication].applicationIconBadgeNumber = badge;
}
}
//訊息推送註冊
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge];
}
- 在專案AppDelegate.m中加入訊息接收處理代理方法。
//處理收到的訊息推送
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//在此處理接收到的訊息。
NSLog(@"Receive remote notification : %@",userInfo);
}
3.Java後臺蘋果推送伺服器推送訊息
package com.kerryzb.util;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import javapns.Push;
import javapns.devices.Device;
import javapns.devices.implementations.basic.BasicDevice;
import javapns.notification.AppleNotificationServerBasicImpl;
import javapns.notification.PushNotificationManager;
import javapns.notification.PushNotificationPayload;
import javapns.notification.PushedNotification;
public class Test
{
public static void main(String[] args) throws Exception
{
String deviceToken = "d4b3c5f3d497554f56f6f9791872666ae06e3b4e7abad6f4792dcd030007db91";
String alert = "給你發信息了";//push的內容
int badge = 3;//圖示小紅圈的數值
String sound = "default";//鈴音
List<String> tokens = new ArrayList<String>();
tokens.add(deviceToken);
String certificatePath = "D:/ZshPush.p12";
String certificatePassword = "123456";//此處注意匯出的證書密碼不能為空因為空密碼會報錯
boolean sendCount = true;
try
{
PushNotificationPayload payLoad = new PushNotificationPayload();
payLoad.addAlert(alert); // 訊息內容
payLoad.addBadge(badge); // iphone應用圖示上小紅圈上的數值
if (!StringUtils.isBlank(sound))
{
payLoad.addSound(sound);//鈴音
}
PushNotificationManager pushManager = new PushNotificationManager();
//true:表示的是產品釋出推送服務 false:表示的是產品測試推送服務
pushManager.initializeConnection(new AppleNotificationServerBasicImpl(certificatePath, certificatePassword, false));
List<PushedNotification> notifications = new ArrayList<PushedNotification>();
// 傳送push訊息
if (sendCount)
{
Device device = new BasicDevice();
device.setToken(tokens.get(0));
PushedNotification notification = pushManager.sendNotification(device, payLoad, true);
notifications.add(notification);
}
else
{
List<Device> device = new ArrayList<Device>();
for (String token : tokens)
{
device.add(new BasicDevice(token));
}
notifications = pushManager.sendNotifications(payLoad, device);
}
pushManager.stopConnection();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Java所需要用到的jar包,可到此下載