1.由于项目的需求,需要在Android APP上实现消息推送功能,所以引用了极光推送(官网:https://www.jiguang.cn/, 文档:http://docs.jiguang.cn/)
2.极光推送是经过考验的大规模app推送平台,极光推送目前每天推送消息数超过20亿条。 开发者集成SDK后,可以通过调用API推送消息。同时,极光推送提供可视化的web端控制台发送通知,统计分析推送效果。 极光推送全面支持 Android, iOS, Winphone 三大手机平台。
3.要在自己项目集成极光推送功能,首先需要在逛网注册一个极光账号,获取AppKey和masterSecret
4.项目集成java SDK,导入maven依赖
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jpush-client</artifactId>
<version>3.4.3</version>
</dependency> <dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jiguang-common</artifactId>
<version>1.1.7</version>
</dependency> <!--以上部分为极光推送所依赖的jar包-->
5.application.yml需要添加的配置
jpush:
appKey: 81a89169e875c793c1e1d862
masterSecret: 630c4f475810e7426f065b14
liveTime: 1000
apnsProduction: false # 是否生成环境,true表示生成环境
6.创建极光推送基本配置信息
@Component("jpushConfig")
public class JpushConfig { /**
* 极光推送的用户名
*/
@Value("${jpush.appKey}")
private String appkey;
/**
* 极光推送的密码
*/
@Value("${jpush.masterSecret}")
private String masterSecret;
/**
* 极光推送设置过期时间
*/
@Value("${jpush.liveTime}")
private String liveTime; public String getAppkey() {
return appkey;
} public void setAppkey(String appkey) {
this.appkey = appkey;
} public String getMasterSecret() {
return masterSecret;
} public void setMasterSecret(String masterSecret) {
this.masterSecret = masterSecret;
} public String getLiveTime() {
return liveTime;
} public void setLiveTime(String liveTime) {
this.liveTime = liveTime;
}
7.编写极光推送工具类
@Service("jpushService")
@Slf4j
public class JpushUtils { @Resource
JpushConfig jpushConfig; /**
* 发送自定义消息,由APP端拦截信息后再决定是否创建通知(目前APP用此种方式)
*
* @param title App通知栏标题
* @param content App通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
* @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
* @param alias 别名数组,设定哪些用户手机能接收信息(为空则所有用户都推送)
* @return PushResult
*/
public PushResult sendCustomPush(String title, String content, Map<String, String> extrasMap, String... alias) throws APIConnectionException, APIRequestException {
ClientConfig clientConfig = ClientConfig.getInstance();
clientConfig.setTimeToLive(Long.parseLong(jpushConfig.getLiveTime()));
// 使用NativeHttpClient网络客户端,连接网络的方式,不提供回调函数
JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey(), null,
clientConfig);
// 设置为消息推送方式为仅推送消息,不创建通知栏提醒
// PushPayload payload = buildCustomPushPayload(title, content, extrasMap, alias);
PushPayload payload = buildCustomPushPayload(title, content, extrasMap, alias);
PushResult result = jpushClient.sendPush(payload);
return result;
} /**
* 发送通知消息
*
* @param title App通知栏标题
* @param content App通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
* @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
* @param tags 标签数组,设定哪些用户手机能接收信息(为空则所有用户都推送)
*/
public PushResult sendPush(String title, String content, Map<String, String> extrasMap, String... tags) throws APIConnectionException, APIRequestException {
ClientConfig clientConfig = ClientConfig.getInstance();
clientConfig.setTimeToLive(Long.valueOf(jpushConfig.getLiveTime()));
// 使用NativeHttpClient网络客户端,连接网络的方式,不提供回调函数
JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey(), null,
clientConfig);
// 设置推送方式
PushPayload payload = buildPushLoadByTags(title, content, extrasMap, tags);
PushResult result = jpushClient.sendPush(payload);
return result;
} /**
* 异步请求推送方式
* 使用NettyHttpClient,异步接口发送请求,通过回调函数可以获取推送成功与否情况
*
* @param title 通知栏标题
* @param content 通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
* @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
* @param alias 需接收的用户别名数组(为空则所有用户都推送)
*/
public void sendPushWithCallback(String title, String content, Map<String, String> extrasMap, String... alias) {
ClientConfig clientConfig = ClientConfig.getInstance();
clientConfig.setTimeToLive(Long.valueOf(jpushConfig.getLiveTime()));
String host = (String) clientConfig.get(ClientConfig.PUSH_HOST_NAME);
NettyHttpClient client = new NettyHttpClient(
ServiceHelper.getBasicAuthorization(jpushConfig.getAppkey(), jpushConfig.getMasterSecret()), null,
clientConfig);
try {
URI uri = new URI(host + clientConfig.get(ClientConfig.PUSH_PATH));
PushPayload payload = buildPushPayload(title, content, extrasMap, alias);
client.sendRequest(HttpMethod.POST, payload.toString(), uri, new NettyHttpClient.BaseCallback() {
@Override
public void onSucceed(ResponseWrapper responseWrapper) {
if (200 == responseWrapper.responseCode) {
log.info("极光推送成功");
} else {
log.info("极光推送失败,返回结果: " + responseWrapper.responseContent);
}
}
});
} catch (URISyntaxException e) {
e.printStackTrace();
} finally {
// 需要手动关闭Netty请求进程,否则会一直保留
client.close();
} } /**
* 设置、更新、设备的 tag, alias 信息。
*
* @param registrationId 设备的registrationId
* @param alias 更新设备的别名属性
* @param tagsToAdd 添加设备的tag属性
* @param tagsToRemove 移除设备的tag属性
*/
public void UpdateDeviceTagAlias(String registrationId, String alias, Set<String> tagsToAdd, Set<String> tagsToRemove) throws APIConnectionException, APIRequestException {
JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey());
jpushClient.updateDeviceTagAlias(registrationId, alias, tagsToAdd, tagsToRemove);
} /**
* 构建Android和IOS的推送通知对象
*
* @return PushPayload
*/
private PushPayload buildPushPayload(String title, String content, Map<String, String> extrasMap, String... alias) {
if (extrasMap == null || extrasMap.isEmpty()) {
extrasMap = new HashMap<String, String>();
}
// 批量删除数组中空元素
String[] newAlias = removeArrayEmptyElement(alias);
return PushPayload.newBuilder().setPlatform(Platform.android_ios())
// 别名为空,全员推送;别名不为空,按别名推送
.setAudience((null == newAlias || newAlias.length == 0) ? Audience.all() : Audience.alias(alias))
// .setAudience(Audience.registrationId("d"))
.setNotification(Notification.newBuilder().setAlert(content)
.addPlatformNotification(
AndroidNotification.newBuilder().setTitle(title).addExtras(extrasMap).build())
.addPlatformNotification(IosNotification.newBuilder().incrBadge(1).addExtras(extrasMap).build())
.build())
.build();
} /**
* 根据标签推送相应的消息
* @param title 推送消息标题
* @param content 推送消息内容
* @param map 推送额外信息
* @param tags 推送的目标标签
* @return
*/
public PushPayload buildPushLoadByTags(String title,String content,Map<String,String> map,String... tags) {
if(map.isEmpty()){
map = new HashMap<>();
}
//批量删除数组中的空元素
String[] newTags = removeArrayEmptyElement(tags);
return PushPayload.newBuilder()
//设置推送平台为安卓
.setPlatform(Platform.android())
//设置标签
.setAudience(Audience.tag(tags))
//设置 推送的标签标题
// 设置通知方式(以alert方式提醒)
.setNotification(Notification.newBuilder().setAlert(content)
.addPlatformNotification(AndroidNotification.newBuilder().setTitle(title).addExtras(map).build()).build())
//sendno int 可选 推送序号 纯粹用来作为 API 调用标识
//离线消息保留时长 推送当前用户不在线时,为该用户保留多长时间的离线消息(默认 86400 (1 天),最长 10 天。设置为 0 表示不保留离线消息,只有推送当前在线的用户可以收到)
//apns_production boolean 可选 APNs是否生产环境 True 表示推送生产环境,False 表示要推送开发环境; 如果不指定则为推送生产环境
//big_push_duration int 可选 定速推送时长(分钟) 又名缓慢推送,把原本尽可能快的推送速度,降低下来,在给定的 n 分钟内,均匀地向这次推送的目标用户推送。最大值为 1440。未设置则不是定速推送
// .setOptions(Options.newBuilder().setApnsProduction(false).setTimeToLive(8600).setBigPushDuration(1).build())
//设置通知内容
// .setMessage(Message.newBuilder().setTitle("").setMsgContent("").setContentType("").build())
.build();
} /**
* 构建Android和IOS的自定义消息的推送消息对象
*
* @return PushPayload
*/
private PushPayload buildCustomPushPayload(String title, String content, Map<String, String> extrasMap, String... alias) {
// 批量删除数组中空元素
String[] newAlias = removeArrayEmptyElement(alias);
return PushPayload.newBuilder().setPlatform(Platform.android_ios())
.setAudience((null == newAlias || newAlias.length == 0) ? Audience.all() : Audience.alias(alias))
.setNotification(Notification.newBuilder().setAlert(content)
.addPlatformNotification(AndroidNotification.newBuilder().setTitle(title).addExtras(extrasMap).build()).build())
.setMessage(Message.newBuilder().setTitle(title).setMsgContent(content).addExtras(extrasMap).build())
.build();
} /**
* 删除别名中的空元素(需删除如:null,""," ")
*
* @param strArray
* @return String[]
*/
private String[] removeArrayEmptyElement(String... strArray) {
if (null == strArray || strArray.length == 0) {
return null;
}
List<String> tempList = Arrays.asList(strArray);
List<String> strList = new ArrayList<String>();
Iterator<String> iterator = tempList.iterator();
while (iterator.hasNext()) {
String str = iterator.next();
// 消除空格后再做比较
if (null != str && !"".equals(str.trim())) {
strList.add(str);
}
}
// 若仅输入"",则会将数组长度置为0
String[] newStrArray = strList.toArray(new String[strList.size()]);
return newStrArray;
}
8.测试类
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class JgTest {
@Autowired
JpushUtils jpushUtils; @Test
public void testSendMessage() throws APIConnectionException, APIRequestException {
String title = "工单受理";
String content = "工单已发起,请开始受理工单信息,谢谢!";
Map<String,String> map = new HashedMap<>();
//设置标签
HashSet hashSet = new HashSet();
hashSet.add("ywb");
//可以设置多个tag别名
//hashSet.add("客服");
map.put("message","额外的message消息"); //13_1711406300 12_1743331095
PushResult pushResult = jpushUtils.sendCustomPush(title, content, map, "17_ywb");
System.out.println(pushResult.getResponseCode());
//log.info(String.valueOf(pushResult.statusCode));
log.info(String.valueOf(pushResult.sendno));
//设置、更新、设备的 tag, alias 信息。140fe1da9e38e9efd3e
jpushUtils.UpdateDeviceTagAlias("140fe1da9ec6c5fc7af",null,hashSet,null);
} @Test
public void testSendMessageByTags() throws APIConnectionException, APIRequestException {
String title = "工单受理new";
String content = "工单已发起,请开始受理工单信息,谢谢!";
Map<String,String> map = new HashedMap<>();
//设置标签
HashSet hashSet = new HashSet();
hashSet.add("ywb");
//可以设置多个tag标签
//hashSet.add("客服");
map.put("message","其他的message消息");
String[] tags = new String[]{"support"};
PushResult pushResult = jpushUtils.sendPush(title, content, map, tags);
System.out.println(pushResult.getResponseCode());
}
}
9.通过账号登录官网可以看到推送历史记录
详细信息
10:注:手机安装相应的App,安卓端需要知道当前注册账号的AppKey,然后就可以收到服务端发送的消息