消息推送
移动推送(Mobile Push)是提供给移动开发者的移动端消息推送服务,通过在App中集成推送功能,进行高效、精准、实时的消息推送,从而使业务及时触达用户,提高用户粘性。
一:导入jar包
<!-- 阿里消息推送 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-push</artifactId>
<version>3.13.5</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.16</version>
</dependency>
注:aliyun-java-sdk-push (3.13.5) 这个在(2020-11-25)时是最新的jar包,如果你是从阿里官方下下来的demo中版本是(3.0.0)这个版本的一下参数是用数字来作为值的。
例:
AndroidOpenType
(旧): 点击通知后动作,1:打开应用 2: 打开应用Activity 3:打开 url 4 : 无跳转逻辑
(新):点击通知后动作。可取值,APPLICATION:打开应用(默认值,ACTIVITY:打开应用AndroidActivityURL:打开URL ,NONE:无跳转;
Type
(旧):0:表示消息(默认为0), 1:表示通知
(新):推送类型。取值:MESSAGE:表示消息。NOTICE:表示通知。
二:定义枚举类
public enum AndroidNotifyTypeEnum {
VIBRATE("VIBRATE", "振动(默认值)"),
SOUND("SOUND", "声音"),
BOTH("BOTH", "声音和振动"),
NONE("NONE", "静音");
private String key;
private String desc;
AndroidNotifyTypeEnum(String key, String desc) {
this.key = key;
this.desc = desc;
}
public String getDesc() {
return desc;
}
public String getKey() {
return key;
}
}
public enum AndroidOpenTypeEnum {
APPLICATION("APPLICATION","打开应用(默认值)"),
ACTIVITY("ACTIVITY","打开应用AndroidActivity"),
URL("URL","打开URL"),
NONE("NONE","无跳转");
private String key;
private String desc;
AndroidOpenTypeEnum(String key, String desc){
this.key = key;
this.desc = desc;
}
public String getKey() {
return key;
}
public String getDesc() {
return desc;
}
}
public enum PushTypeEnum {
MESSAGE("MESSAGE","消息"),
NOTIFICATION("NOTICE","通知");
private String key;
private String desc;
PushTypeEnum(String key, String desc){
this.key = key;
this.desc = desc;
}
public String getKey() {
return key;
}
public String getDesc() {
return desc;
}
}
public enum TargetEnum {
DEVICE("DEVICE","根据设备推送"),
ACCOUNT("ACCOUNT","根据账号推送"),
ALIAS("ALIAS","根据别名推送"),
TAG("TAG","根据标签推送"),
ALL("ALL","推送给全部设备(同一种DeviceType的两次全推的间隔至少为1秒)"),
TBD("TBD","初始化持续推送,推送目标由后续的ContinuouslyPush接口指定");
private String key;
private String desc;
TargetEnum(String key, String desc){
this.key = key;
this.desc = desc;
}
public String getKey() {
return key;
}
public String getDesc() {
return desc;
}
}
public enum RedisKeyEnum {
/**
*
*/
ALI_MESSAGE_PUSH("RedisMap:ALI_MESSAGE_PUSH","消息推送-设备id");
;
private String key;
private String desc;
RedisKeyEnum(String key, String desc){
this.key = key;
this.desc = desc;
}
public String getDesc() {
return desc;
}
public String getKey() {
return key;
}
}
三:将需要的参数配置到yml文件
四:保存设备id到redis中
在登录的时候将设备id保存到redis中
private static StringRedisTemplate redisTemplate;
/**
* 将值保存到redis的一个map中
* @param key redis的key
* @param hashKey map的key
* @param value 值
*/
public static void hPut(String key, String hashKey, String value) {
redisTemplate.opsForHash().put(key, hashKey, value);
}
/**
* 获取保存在redis的map中的某一个值
* @param redisKey redis的key
* @param hashKey map的key
* @return
*/
public static String hget(String redisKey,String hashKey) {
Object obj = redisTemplate.opsForHash().get(redisKey, hashKey);
String rsp = obj == null ? "" : obj.toString();
return rsp;
}
// 保存设备id 将用户id最为key
RedisUtil.hPut(RedisKeyEnum.ALI_MESSAGE_PUSH.getKey(), String.valueOf("用户id"), "前端传的设备id");
五:推送消息工具类
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.push.model.v20160801.PushRequest;
import com.aliyuncs.push.model.v20160801.PushResponse;
import com.jianxun.nash.common.enums.*;
import com.jianxun.nash.common.exception.SystemException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author 17347
*/
@Component
public class AdvancedPushUtils {
private static final Logger log = LoggerFactory.getLogger(AdvancedPushUtils.class);
@Value("${aliMessagePush.accessKeyId}")
private String accessKeyId;
@Value("${aliMessagePush.accessKeySecret}")
private String accessKeySecret;
@Value("${aliMessagePush.appKey}")
private Long appKey;
private static final String REGION_HANGZHOU = "cn-hangzhou";
/**
* 推送信息到指定Android用户
* @param userId
* @param message
* @param title
* @throws Exception
*/
public void sendMessageByUserId(int userId,String message,String title) throws Exception {
// 获取保存在redis中的设备id
String deviceID = RedisUtil.hget(RedisKeyEnum.ALI_MESSAGE_PUSH.getKey(), String.valueOf(userId));
if(StringUtils.isBlank(deviceID)) {
log.info("用户未绑定deviceID");
return ;
}
log.info("对deviceID:" + deviceID + "的用户推送信息");
PushResponse pushResponse = pushNoticeToAndroidToAccount(deviceID, message, title, PushTypeEnum.MESSAGE.getKey(),null);
if (pushResponse != null){
log.info("针对deviceID:" + deviceID + "的信息推送成功!");
log.info("RequestId:" + pushResponse.getRequestId());
log.info("MessageId:" + pushResponse.getMessageId());
}else {
log.info("针对registId:" + deviceID + "的信息推送失败!");
}
}
/**
* 推送通知到指定Android用户
* @param userId
* @param title
* @param message
* @param summary
* @throws Exception
*/
public void sendNoticeByUserId(int userId,String title,String message, String summary) throws Exception {
String deviceID = RedisUtil.hget(RedisKeyEnum.ALI_MESSAGE_PUSH.getKey(), String.valueOf(userId));
if (deviceID == null) {
log.info("用户未绑定deviceID");
return;
}
log.info("对deviceID:" + deviceID + "的用户推送通知");
PushResponse pushResponse = pushNoticeToAndroidToAccount(deviceID, message, title, PushTypeEnum.NOTIFICATION.getKey(), summary);
if (pushResponse != null) {
log.info("针对deviceID:" + deviceID + "的通知推送成功!");
log.info("RequestId:" + pushResponse.getRequestId());
log.info("MessageId:" + pushResponse.getMessageId());
} else {
log.info("针对registId:" + deviceID + "的通知推送失败!");
}
}
/**
* 阿里 推送通知给android
* <p>
* 参见文档 https://help.aliyun.com/document_detail/30082.html
*/
public PushResponse pushNoticeToAndroidToAccount(String deviceID, String message, String title, String pushType, String map) throws ClientException {
IClientProfile profile = DefaultProfile.getProfile(REGION_HANGZHOU, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
// 检查这个设备id是否有
if (StringUtils.isBlank(deviceID)) {
SystemException.myException(ExceptionMsg.ASSERT_NOT_NULL);
}
PushRequest pushRequest = new PushRequest();
// 设置NotificationChannel参数,具体用途请参见常见问题:Android 8.0以上设备通知接收不到。
// 值要与前端相同 也可以不要
pushRequest.setAndroidNotificationChannel("hrss");
// 提交方式
pushRequest.setProtocol(ProtocolType.HTTPS);
pushRequest.setMethod(MethodType.POST);
// 推送目标 推送给指定设备—id
pushRequest.setPushType(pushType);
pushRequest.setTarget(TargetEnum.DEVICE.getKey());
pushRequest.setTargetValue(deviceID);
pushRequest.setAndroidNotifyType(AndroidNotifyTypeEnum.VIBRATE.getKey());
pushRequest.setAndroidOpenType(AndroidOpenTypeEnum.APPLICATION.getKey());
pushRequest.setDeviceType(EquipmentEnum.ALL_EQUIPMENTENUM.getKey());
// 推送内容 顺序 标题(Title),内容(Body),摘要(summary) (map)AndroidExtParameters
pushRequest.setTitle(title);
pushRequest.setBody(message);
pushRequest.setAndroidExtParameters(map);
pushRequest.setAppKey(appKey);
PushResponse acsResponse = client.getAcsResponse(pushRequest);
return acsResponse;
}
}
测试
@Autowired
AdvancedPushUtils advancedPushUtils;
@Test
public void test07() throws Exception {
// deviceID 前端给的用于测试
advancedPushUtils.pushNoticeToAndroidToAccount("b6d5faa73d8842178be06da3e8c267b0","你好,今天的代码请签收","签署", PushTypeEnum.NOTIFICATION.getKey(),null);
}