公司要求做一個服務器端的推送功能,客戶端主要是以移動端為主,混合式的app前端,在友盟官網看了下demo,有后台服務器端,前端主要是原生安卓,IOS還有windos.所以根據自身實際能力,按照demo先弄了個原生安卓的前端和java的后台,調試成功。主要測試2個功能:單點推送客戶端,推送所有客戶端。
本次實踐也遇到了很多坑。大致步驟就是先在友盟官網申請賬號,然后注冊包名,之后會生成一個appkey,message secret,master secret.這3個參數必須和安卓的mainfast當中注冊的值是一樣的。友盟官網注冊的包名必須和客戶端生成的包名一致。
1.第一步:新建包名

2.第二步:包名新建完后記錄下appkey,message secret,master secret

3.第三步:在安卓的mainfast的配置文件中的key以及message_secret必須和網頁中生成的一致

4.第四步:進入消息管理后台,添加測試設備



5.第五步:設置推送消息


Response Code : 400
{"ret":"FAIL","data":{"error_code":"2027"}}
Failed to send the notification!
2027是簽名失敗,我以為需要在安卓app打包的時候需要用
於是我進行簽名打包,但是依然無作用


然后繼續找問題,后來發現是master secret和message secret寫反了,改過來之后OK了

6.由於是開發服務器端調用友盟推送,所以必須設置服務器的ip地址,下圖告訴你如何查看本機的外網ip地址

以上都是些設置,介紹一下消息推送所使用的一些場景
后台開啟一個定時任務,比如每天晚上10點像全體用戶發送推送消息。單點發送可以根據唯一的devicetoken發送消息給用戶,因此可以把這個token和數據庫中用戶名進行綁定,根據用戶名查詢出token給指定用戶發送即可。
其他代碼可以通過下面的友盟推送java服務端代碼以及友盟推送安卓客戶端代碼查看,這里主要對其進行了封裝,各位可以看下有什么更好的方法封裝,可以指出。
YoumengAndroidMain是主調用類
package youmeng;
import java.util.HashMap;
import java.util.Map;
import pushandroid.YoumengAndroidPush;
public class YoumengAndroidMain {
public static void main(String[] args) {
//1.廣播,通過友盟推送給所有人發送信息
// try {
// YoumengAndroidMain yoMain = new YoumengAndroidMain();//這個在框架里可以直接用注入
// Map mapAndroidAll = new HashMap<String, String>();
// mapAndroidAll.put("appkey", "59e76d978f4a9d6888000113");
// mapAndroidAll.put("mastersecret", "6darv0eftbwqgzfprg40muvyzfpjrhpe");
// mapAndroidAll.put("ticker", "2017年10月19日ticker");
// mapAndroidAll.put("title", "2017年10月19日title");
// mapAndroidAll.put("text", "2017年10月19日text");
// Map map = new HashMap<String, String>();
// map.put("extrafieldkey", "key");
// map.put("extrafieldvalue", "value");
// mapAndroidAll.put("extrafield", map);
// yoMain.sendYoumengAndroidAll(mapAndroidAll);
// } catch (Exception e) {
// System.out.println("發送失敗");
// }
//2.通過友盟給指定用戶推送
try {
YoumengAndroidMain yoMain = new YoumengAndroidMain();//這個在框架里可以直接用注入
Map mapAndroidAll = new HashMap<String, String>();
mapAndroidAll.put("appkey", "59e76d978f4a9d6888000113");
mapAndroidAll.put("mastersecret", "6darv0eftbwqgzfprg40muvyzfpjrhpe");
mapAndroidAll.put("devicetoken", "Am5T2vzQBapWZ1bBfdNKKk6-PTBcV2gZPPX8i5V4r9dO");
mapAndroidAll.put("ticker", "2017年10月19日ticker");
mapAndroidAll.put("title", "2017年10月19日title");
mapAndroidAll.put("text", "2017年10月19日text");
Map map = new HashMap<String, String>();
map.put("extrafieldkey", "key");
map.put("extrafieldvalue", "value");
mapAndroidAll.put("extrafield", map);
yoMain.sendYoumengAndroidUnicast(mapAndroidAll);
} catch (Exception e) {
System.out.println("發送失敗");
}
}
/**
* 廣播,通過友盟給所有人發送信息,在定時任務中定時執行全員發送
* appkey,mastersecret是必傳字段,ticker,title,text,extrafieldkey,extrafieldvalue是選填字段
*/
public void sendYoumengAndroidAll(Map model) throws Exception{
YoumengAndroidPush youMain = new YoumengAndroidPush();//到框架里的時候用@Component放到工廠里,用Autoriwed注入
youMain.sendAndroidBroadcast(model);
}
/**
* 通過友盟發送給指定用戶,這個根據devicetoken給指定的app發送消息,這個devicetoken在給用戶注冊的時候可以記錄下來,存到數據庫
* 這個token可以跟用戶名進行綁定,根據用戶名去查找token,這樣就可以給指定用戶發送消息了
*/
public void sendYoumengAndroidUnicast(Map model) throws Exception{
YoumengAndroidPush youmengPush = new YoumengAndroidPush();
youmengPush.sendAndroidUnicast(model);
}
}
YoumengAndroidPush.java主要通過httpclient將參數封裝傳到友盟進行推送。
package pushandroid;
import java.util.Map;
import pushandroid.android.AndroidBroadcast;
import pushandroid.android.AndroidUnicast;
public class YoumengAndroidPush {
private String timestamp = null;
private PushClient client = new PushClient();
/**
* 像所有的用戶推送消息
* appkey和mastersecret為必填項,ticker,title,text,extrafield為選填
* 群發
*/
public void sendAndroidBroadcast(Map model) throws Exception {
if(null == model)
return;
if(null == model.get("appkey") || null == model.get("mastersecret"))
return;
String appkey = (String) model.get("appkey");
String masterSecret = (String) model.get("mastersecret");
AndroidBroadcast broadcast = new AndroidBroadcast(appkey,masterSecret);
String ticker = (String) (model.get("ticker") == null?"測試":model.get("ticker"));
String title = (String) (model.get("title")==null?"測試":model.get("title"));
String text = (String) (model.get("text")==null?"測試,您好":model.get("text"));
broadcast.setTicker(ticker);
broadcast.setTitle(title);
broadcast.setText(text);
broadcast.goAppAfterOpen();
broadcast.setDisplayType(AndroidNotification.DisplayType.NOTIFICATION);
broadcast.setProductionMode();
if(null != model.get("extrafield")){
Map map = (Map) model.get("extrafield");
String extrafieldkey = (String) (map.get("extrafieldkey")==null?"":map.get("extrafieldkey"));
String extrafieldvalue = (String) (map.get("extrafieldvalue")==null?"":map.get("extrafieldvalue"));
broadcast.setExtraField(extrafieldkey, extrafieldvalue);
}
client.send(broadcast);
}
/**
* 單點發送,通過友盟推送給指定用戶,這個token可以跟用戶名進行綁定,根據用戶名去查找token,這樣就可以給指定用戶發送消息了
* appkey,mastersecret,devicetoken是必傳字段,ticker,title,text,extrafieldkey,extrafieldvalue是選填字段
*/
public void sendAndroidUnicast(Map model) throws Exception {
if(null == model)
return;
if(null == model.get("appkey") || null == model.get("mastersecret") || null==model.get("devicetoken"))
return;
String appkey = (String) model.get("appkey");
String masterSecret = (String) model.get("mastersecret");
AndroidUnicast unicast = new AndroidUnicast(appkey,masterSecret);
String ticker = (String) (model.get("ticker") == null?"測試":model.get("ticker"));
String title = (String) (model.get("title")==null?"測試":model.get("title"));
String text = (String) (model.get("text")==null?"測試,您好":model.get("text"));
String devicetoken = (String) model.get("devicetoken");//上面已經判斷過空的情況
unicast.setDeviceToken( devicetoken);
unicast.setTicker(ticker);
unicast.setTitle(title);
unicast.setText(text);
unicast.goAppAfterOpen();
unicast.setDisplayType(AndroidNotification.DisplayType.NOTIFICATION);
unicast.setProductionMode();
if(null != model.get("extrafield")){
Map map = (Map) model.get("extrafield");
String extrafieldkey = (String) (map.get("extrafieldkey")==null?"test":map.get("extrafieldkey"));
String extrafieldvalue = (String) (map.get("extrafieldvalue")==null?"helloworld":map.get("extrafieldvalue"));
unicast.setExtraField(extrafieldkey, extrafieldvalue);
}
client.send(unicast);
}
public static void main(String[] args) {
}
}
原文鏈接:
http://www.jianshu.com/p/453f2ead8d04
關注我的公眾號,都是滿滿的干貨!
