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

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

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

4.第四步:進(jìn)入消息管理后臺,添加測試設(shè)備



5.第五步:設(shè)置推送消息


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


然后繼續(xù)找問題,后來發(fā)現(xiàn)是master secret和message secret寫反了,改過來之后OK了

6.由于是開發(fā)服務(wù)器端調(diào)用友盟推送,所以必須設(shè)置服務(wù)器的ip地址,下圖告訴你如何查看本機(jī)的外網(wǎng)ip地址

以上都是些設(shè)置,介紹一下消息推送所使用的一些場景
后臺開啟一個定時任務(wù),比如每天晚上10點(diǎn)像全體用戶發(fā)送推送消息。單點(diǎn)發(fā)送可以根據(jù)唯一的devicetoken發(fā)送消息給用戶,因此可以把這個token和數(shù)據(jù)庫中用戶名進(jìn)行綁定,根據(jù)用戶名查詢出token給指定用戶發(fā)送即可。
其他代碼可以通過下面的友盟推送java服務(wù)端代碼以及友盟推送安卓客戶端代碼查看,這里主要對其進(jìn)行了封裝,各位可以看下有什么更好的方法封裝,可以指出。
YoumengAndroidMain是主調(diào)用類
package youmeng;
import java.util.HashMap;
import java.util.Map;
import pushandroid.YoumengAndroidPush;
public class YoumengAndroidMain {
public static void main(String[] args) {
//1.廣播,通過友盟推送給所有人發(fā)送信息
// 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("發(fā)送失敗");
// }
//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("發(fā)送失敗");
}
}
/**
* 廣播,通過友盟給所有人發(fā)送信息,在定時任務(wù)中定時執(zhí)行全員發(fā)送
* appkey,mastersecret是必傳字段,ticker,title,text,extrafieldkey,extrafieldvalue是選填字段
*/
public void sendYoumengAndroidAll(Map model) throws Exception{
YoumengAndroidPush youMain = new YoumengAndroidPush();//到框架里的時候用@Component放到工廠里,用Autoriwed注入
youMain.sendAndroidBroadcast(model);
}
/**
* 通過友盟發(fā)送給指定用戶,這個根據(jù)devicetoken給指定的app發(fā)送消息,這個devicetoken在給用戶注冊的時候可以記錄下來,存到數(shù)據(jù)庫
* 這個token可以跟用戶名進(jìn)行綁定,根據(jù)用戶名去查找token,這樣就可以給指定用戶發(fā)送消息了
*/
public void sendYoumengAndroidUnicast(Map model) throws Exception{
YoumengAndroidPush youmengPush = new YoumengAndroidPush();
youmengPush.sendAndroidUnicast(model);
}
}
YoumengAndroidPush.java主要通過httpclient將參數(shù)封裝傳到友盟進(jìn)行推送。
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為必填項(xiàng),ticker,title,text,extrafield為選填
* 群發(fā)
*/
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);
}
/**
* 單點(diǎn)發(fā)送,通過友盟推送給指定用戶,這個token可以跟用戶名進(jìn)行綁定,根據(jù)用戶名去查找token,這樣就可以給指定用戶發(fā)送消息了
* 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");//上面已經(jīng)判斷過空的情況
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) {
}
}