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.创建应用

根据官网提示创建应用,并且得到 AppKeyMaster 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用户成功

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
安卓推送方案及比较 经常有朋友困扰于Android上面实现推送的技术,希望知道各种方案的优缺点、性能、开发难度等,于是特意写了这篇文章。 方案一: Google官方的服务: 但,通过对比研究发现C2DM机制存在以下缺点: 1)GCM要求Android系统必须是2.2以上的版本,所以对于不少2.2以前的系统没法推送 2)国内服务不稳定。而且不少国内的终端厂商纷纷把Google的服务去掉,替换上自己的。 3)需要用户绑定Google账号,但不少国内用户没有Google账号。 方案二: 利用MQTT协议,broker做代理服务器,但是随着用户的增多这个方案会有问题,因为broker的连接数有上限,到了一定程度后就无法连接了,这也就导致消息很难发送出去。 总之,连接数量有限制。 方案三: 基于XMPP协议,很多人都建议使用这个,谷歌官方的C2DM也是基于XMPP研发的,使用这个方案不会依赖android系统,也不依赖于谷歌服务器。 •XMPP协议比较费电费流量,对当前智能机的消耗太大 •在窄带网络和不稳定的(手机)网络都不是最优的选择。 方案四: 最近新出的一种是APNS,这个也不需要自己架设服务器(可以查看http://www.push-notification.mobi/),很简单,自己不用开发服务端。不过很少有人去用,不是很稳定 主要有以下特点: •快速集成:提供一种比C2DM更加快捷的使用方式,避免各种限制. •无需架设服务器:通过使用"云服务",减少额外服务器负担. •可以同时推送消息到网站页面,android 手机 •耗电少,占用流量少. 第三方服务: 目前也有不少第三方提供了推送服务,由于接入简单、服务比较专业可靠、还提供报表等,不少国内开发者和企业都采用这种方案。比如国外的parse、pubnub,国内的个推,都是这类。36kr前段时间有报道,新浪微博就是用的一家叫“个推”的第三方服务(有兴趣的朋友可以前往查看 http://www.igetuicom) 特点: •方便,易集成 •没有C2DM中的版本限制和必须用gmail绑定 •云服务,不用架设自己的服务器 •系统稳定、专业,能够承受高并发支持 •简单高效,并且省电

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值