Android推送
Android推送
前言
手机推送服务是指服务器定向将信息实时送达手机的服务。与常见的轮询方式(伪推送),相比区别主要在于两点,一是否长联网,二是到达实时性。推送服务是长联网的,一般到达手机的延迟在0.1-0.5秒左右,而轮询方式(伪推送)不是长联网的,达到延迟时间则根据轮
询时间的不同为1-10分钟,也有延迟1小时或一天的情况。一般来说,自黑莓,苹果和安卓采用标准长连接推送方式后,手机推送服务就特指能够实时到达的形式。
手机推送服务的原理很简单,就是通过建立一条手机与服务器的连接链路,当有消息需要发送到手机时,通过此链路发送即可。
** 推送服务的使用流程虽然略有差别但是大致都和 iOS的APNs 相似:**
1、首先是应用程序注册消息推送。
2、 iOS 向 APNs Server 取得deviceToken。应用程序接受deviceToken。
3、应用程序将deviceToken发送给PUSH服务端程序。
4、 服务端程序向APNs服务发送消息。
5、APNs服务将消息发送给iPhone应用程序。
一、实现方式
方案1、使用C2DM服务(Google Cloud Messaging)
简介:Google推出的云消息服务,即第二代的G2DM。
优点:Google提供的服务、原生、简单,无需实现和部署服务端。
缺点:Android版本限制(必须大于2.2版本),该服务在国内不够稳定、需要用户绑定Goo
gle帐号,受限于Google。
方案2、使用XMPP协议(Openfire + Spark + Smack)
简介:基于XML协议的通讯协议,前身是Jabber,已由IETF国际标准化组织完成了标准化工作。
优点:协议成熟、强大、可扩展性强、主要应用于许多聊天系统中,且已有开源的Java版的开发实例androidpn。
缺点:协议较复杂、冗余(基于XML)、费流量、费电,部署硬件成本高。
方案3、使用MQTT协议
简介:轻量级的、基于代理的“发布/订阅”模式的消息传输协议。
优点:协议简洁、小巧、可扩展性强、省流量、省电,应用到企业领域,且已有C++版的服务端组件rsmb。
缺点:不够成熟、实现较复杂、服务端组件 rsmb 不开源,部署硬件成本较高。
方案4、使用第三方推送服务
简介:通过嵌入SDK使用第三方提供的推送服务,主流的有百度云推送,极光推送,智游推送,Urban Airship,个推,PUBNUB,蝴蝶等。
优点:稳定,成熟,节省开发和探索时间,相对自己开发成本低,推送管理界面及统计程序完善。
缺点:有程序嵌入顾虑 [2]
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
二、实现步骤
极光推送官网:https://www.jiguang.cn/
1.创建应用
根据官网提示创建应用,并且得到 AppKey 和 Master Secret
2.引入依赖
<!-- 极光推送 -->
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jpush-client</artifactId>
<version>3.4.8</version>
</dependency>
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack</artifactId>
<version>0.6.12</version>
</dependency>
3.创建常量类
package common.constant;
/**
* 极光推送常量
* @author gsz
* @date 2022/03/18 14:21
*/
public class JpushConstants {
/**
* 根据官网创建自己的key 和 密匙
*/
//应用key
public static final String APPKEY = "32e0xxxxxxxxxxxa490";
//密匙
public static final String MASTERSECRET = "6fc9xxxxxxxxxxx0af9";
}
4.创建工具类
package common.util.jpush;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.Notification;
import common.constant.JpushConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 极光推送工具类
* @author gsz
* @date 2022/03/18 10:40
*/
public class JpushUtils {
public static final Logger log = LoggerFactory.getLogger(JpushUtils.class);
private static JPushClient jPushClient = new JPushClient(JpushConstants.MASTERSECRET, JpushConstants.APPKEY);
/**
* @description: 推送给所有Android用户
* @author: gsz
* @date: 2022/3/18 14:58
* @param notification_title 通知标题
* @param msg_title 标题
* @param msg_content 内容
* @param extrasparam 附加参数
* @return 0推送失败,1推送成功
*/
public static int sendToAllAndroid(String notification_title, String msg_title, String msg_content, String extrasparam){
int resule = 0;
try {
PushPayload pushPayload = JpushUtils.buildPushObject_android_all_alertWithTitleAll(notification_title, msg_title, msg_content, extrasparam);
PushResult pushResult = jPushClient.sendPush(pushPayload);
if (pushResult.getResponseCode() == 200){
resule = 1;
}
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIRequestException e) {
e.printStackTrace();
} catch (Exception e) {
log.error("推送给所有Android用户Error");
e.printStackTrace();
}
return resule;
}
/**
* @description:
* @author: gsz
* @date: 2022/3/18 15:09
* @param notification_title 通知标题
* @param msg_title 标题
* @param msg_content 内容
* @param extrasparam 附加参数
* @param alias 别名
* @return 0推送失败,1推送成功
*/
public static int sendToOneAndroid(String notification_title, String msg_title, String msg_content, String extrasparam, String alias) {
int resule = 0;
try {
PushPayload pushPayload = JpushUtils.buildPushObject_android_all_alertWithTitle(notification_title, msg_title, msg_content, extrasparam, null, alias);
PushResult pushResult = jPushClient.sendPush(pushPayload);
if (pushResult.getResponseCode() == 200){
resule = 1;
}
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIRequestException e) {
e.printStackTrace();
} catch (Exception e) {
log.error("推送给指定Android用户Error");
e.printStackTrace();
}
return resule;
}
private static PushPayload buildPushObject_android_all_alertWithTitleAll(String notification_title, String msg_title, String msg_content, String extrasparam) {
return PushPayload.newBuilder()
.setPlatform(Platform.android())
.setAudience(Audience.all())
.setNotification(Notification.newBuilder()
.addPlatformNotification(AndroidNotification.newBuilder()
.setAlert(msg_content)
.setTitle(msg_title).addExtra("type", extrasparam)
.build())
.build())
.setMessage(Message.newBuilder()
.setMsgContent(msg_content)
.setTitle(msg_title)
.addExtra("status", extrasparam)
.build())
.setOptions(Options.newBuilder()
.setApnsProduction(false)
.setSendno(1)
.setTimeToLive(86400)
.build())
.build();
}
private static PushPayload buildPushObject_android_all_alertWithTitle(String notification_title, String msg_title, String msg_content, String extrasparam, String type, String value) {
return PushPayload.newBuilder()
//指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
.setPlatform(Platform.android())
//指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
//根据别名推送
.setAudience(Audience.alias(value))
//jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
.setNotification(Notification.newBuilder()
//指定当前推送的android通知
.addPlatformNotification(AndroidNotification.newBuilder()
.setAlert(msg_content)
.setTitle(msg_title)
//此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
.addExtra("type", extrasparam)
.build())
.build()
)
//Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
// sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
// [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
.setMessage(Message.newBuilder()
.setMsgContent(msg_content)
.setTitle(msg_title)
// .addExtra("message extras key",extrasparam)
.addExtra("status", extrasparam)
.build())
.setOptions(Options.newBuilder()
//此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
.setApnsProduction(false)
//此字段是给开发者自己给推送编号,方便推送者分辨推送记录
.setSendno(1)
//此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
.setTimeToLive(86400)
.build())
.build();
}
}
5.测试
/**
* @description: 推送给所有Android用户
* @author: gsz
* @date: 2022/3/18 15:01
*/
@Test
public void jpushTextToAll() {
if (JpushUtils.sendToAllAndroid("推送给所有Android用户",
"标题", "测试文本", "101") == 1){
System.out.println("推送给所有Android用户成功");
}
}
/**
* @description: 推送给指定Android用户
* @author: gsz
* @date: 2022/3/18 15:01
*/
@Test
public void jpushTextToOne() {
// 注: aaaaaa 为指定的设备码
if (JpushUtils.sendToOneAndroid("推送给指定Android用户",
"标题", "测试文本", "101","aaaaaa") == 1){
System.out.println("推送给指定Android用户成功");
}
}
输出结果分别是:
推送给所有Android用户成功
推送给指定Android用户成功