精华内容
下载资源
问答
  • 一个简单的极光推送例子,服务器端推送至对应的客户端的。在JPushModel文件设置极光推送对应的Key和Secret就可以直接运行测试了
  • java二次开发接微信公众号接口,实现根据用户授权,获取用户code,再获取openid,然后向其推送模版消息
  • 最全极光推送服务端

    热门讨论 2014-08-04 11:40:16
    本例子为极光推送服务端程序,本代码根据极光推送官网官方文档真情编写,代码齐全,保证您看完马上能够应用到自己的项目中。无论你要做推聊类app还是推送服务类app,希望都能帮到你们!
  • 极光推送在众多的消息推送里,口碑算是很好的,项目中我负责的是这一块,就整理了这篇博客帮助记忆; 极光推送官方SDK文档:https://docs.jiguang.cn/jpush/server/sdk/java_sdk/ 错误码信息:...

    极光推送在众多的消息推送里,口碑算是很好的,项目中我负责的是这一块,就整理了这篇博客帮助记忆;

    极光推送官方SDK文档:https://docs.jiguang.cn/jpush/server/sdk/java_sdk/

    错误码信息:https://docs.jiguang.cn/jpush/server/push/rest_api_v3_push/#_19

    工具类:

    import java.util.ArrayList;
    import java.util.List;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    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.IosNotification;
    import cn.jpush.api.push.model.notification.Notification;
    import cn.jpush.api.schedule.ScheduleResult;
    
    /**
     * @author Zhang
     * @date 2018年11月14日
     * @description: 极光推送工具类
     */ 
    public class JpushClientUtil {
    	
    	private static Logger logger = LoggerFactory.getLogger(JpushClientUtil.class);
     
        private final static String APPKER = "************";
     
        private final static String MASTERSECRET = "**********";
     
        private static JPushClient jPushClient = new JPushClient(MASTERSECRET,APPKER);
        
        private JpushClientUtil() {
            throw new AssertionError("不能产生该对象");
        }
        /*
        public static void main(String[] args) {
        	List<String> alias = new ArrayList<String>();
        	alias.add("276");
        	alias.add("231");
        	sendToRegistrationId(alias, "测试", "测试信息", "测试信息", "https://www.baidu.com");
    //    	sendToRegistrationId2(alias, "测试", "测试信息", "测试信息", "https://www.baidu.com","2018-11-23 17:05:25");
    //    	sendToAllAndroid("测试", "测试信息", "测试信息", "https://www.baidu.com");
    //    	sendToAllIos("测试", "测试信息", "测试信息", "https://www.baidu.com");
    	}
        */
        /**
         * 推送给设备标识参数的用户
         * @param alias 设备标识
         * @param notification_title 通知内容标题
         * @param msg_title 消息内容标题
         * @param msg_content 消息内容
         * @param extrasparam 扩展字段(通常传跳转的链接)
         * @return 0推送失败,1推送成功
         */
        public static int sendToRegistrationId( List<String> alias,String notification_title, String msg_title, String msg_content, String extrasparam) {
        	JPushClient jPushClient = new JPushClient(MASTERSECRET,APPKER);
            int result = 0;
            try {
                PushPayload pushPayload= JpushClientUtil.buildPushObject_all_alias_alertWithTitle(alias,notification_title,msg_title,msg_content,extrasparam);
                PushResult pushResult=jPushClient.sendPush(pushPayload);
                if(pushResult.getResponseCode()==200){
                    result=1;
                }
                logger.info("[极光推送]PushResult result is " + pushResult);
            } catch (APIConnectionException e) {
            	logger.error("[极光推送]Connection error. Should retry later. ", e);
            } catch (APIRequestException e) {
            	logger.error("[极光推送]Error response from JPush server. Should review and fix it. ", e);
            	logger.info("[极光推送]HTTP Status: " + e.getStatus());
            	logger.info("[极光推送]Error Code: " + e.getErrorCode());
            	logger.info("[极光推送]Error Message: " + e.getErrorMessage());
            }
     
             return result;
        }
     
        /**
         * 推送给设备标识参数的用户(定时)
         * @param alias 设备标识
         * @param notification_title 通知内容标题
         * @param msg_title 消息内容标题
         * @param msg_content 消息内容
         * @param extrasparam 扩展字段
         * @param time 格式:yyyy-MM-dd HH:mm:ss
         * @return 0推送失败,1推送成功
         */
        public static int sendToRegistrationId2( List<String> alias,String notification_title, String msg_title, String msg_content, String extrasparam, String time) {
        	JPushClient jPushClient = new JPushClient(MASTERSECRET,APPKER);
            int result = 0;
            try {
                PushPayload pushPayload= JpushClientUtil.buildPushObject_all_alias_alertWithTitle(alias,notification_title,msg_title,msg_content,extrasparam);
                ScheduleResult scheduleResult=jPushClient.createSingleSchedule("点呗生活", time, pushPayload);
                if(scheduleResult.getResponseCode()==200){
                    result=1;
                }
                logger.info("[极光推送]ScheduleResult result is " + scheduleResult);
            } catch (APIConnectionException e) {
            	logger.error("[极光推送]Connection error. Should retry later. ", e);
            } catch (APIRequestException e) {
            	logger.error("[极光推送]Error response from JPush server. Should review and fix it. ", e);
            	logger.info("[极光推送]HTTP Status: " + e.getStatus());
            	logger.info("[极光推送]Error Code: " + e.getErrorCode());
            	logger.info("[极光推送]Error Message: " + e.getErrorMessage());
            }
     
             return result;
        }    
        
        /**
         * 发送给所有安卓用户
         * @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 result = 0;
            try {
                PushPayload pushPayload= JpushClientUtil.buildPushObject_android_all_alertWithTitle(notification_title,msg_title,msg_content,extrasparam);
                PushResult pushResult=jPushClient.sendPush(pushPayload);
                if(pushResult.getResponseCode()==200){
                    result=1;
                }
                logger.info("[极光推送]PushResult result is " + pushResult);
            } catch (APIConnectionException e) {
            	logger.error("[极光推送]Connection error. Should retry later. ", e);
            } catch (APIRequestException e) {
            	logger.error("[极光推送]Error response from JPush server. Should review and fix it. ", e);
            	logger.info("[极光推送]HTTP Status: " + e.getStatus());
            	logger.info("[极光推送]Error Code: " + e.getErrorCode());
            	logger.info("[极光推送]Error Message: " + e.getErrorMessage());
            }
     
             return result;
        }
     
        /**
         * 发送给所有IOS用户
         * @param notification_title 通知内容标题
         * @param msg_title 消息内容标题
         * @param msg_content 消息内容
         * @param extrasparam 扩展字段
         * @return 0推送失败,1推送成功
         */
        public static int sendToAllIos(String notification_title, String msg_title, String msg_content, String extrasparam) {
            int result = 0;
            try {
                PushPayload pushPayload= JpushClientUtil.buildPushObject_ios_all_alertWithTitle(notification_title,msg_title,msg_content,extrasparam);
                PushResult pushResult=jPushClient.sendPush(pushPayload);
                if(pushResult.getResponseCode()==200){
                    result=1;
                }
                logger.info("[极光推送]PushResult result is " + pushResult);
            } catch (APIConnectionException e) {
            	logger.error("[极光推送]Connection error. Should retry later. ", e);
            } catch (APIRequestException e) {
            	logger.error("[极光推送]Error response from JPush server. Should review and fix it. ", e);
            	logger.info("[极光推送]HTTP Status: " + e.getStatus());
            	logger.info("[极光推送]Error Code: " + e.getErrorCode());
            	logger.info("[极光推送]Error Message: " + e.getErrorMessage());
            }
     
             return result;
        }
     
        /**
         * 发送给所有用户
         * @param notification_title 通知内容标题
         * @param msg_title 消息内容标题
         * @param msg_content 消息内容
         * @param extrasparam 扩展字段
         * @return 0推送失败,1推送成功
         */
        public static int sendToAll( String notification_title, String msg_title, String msg_content, String extrasparam) {
            int result = 0;
            try {
                PushPayload pushPayload= JpushClientUtil.buildPushObject_android_and_ios(notification_title,msg_title,msg_content,extrasparam);
                PushResult pushResult=jPushClient.sendPush(pushPayload);
                if(pushResult.getResponseCode()==200){
                    result=1;
                }
                logger.info("[极光推送]PushResult result is " + pushResult);
            } catch (APIConnectionException e) {
            	logger.error("[极光推送]Connection error. Should retry later. ", e);
            } catch (APIRequestException e) {
            	logger.error("[极光推送]Error response from JPush server. Should review and fix it. ", e);
            	logger.info("[极光推送]HTTP Status: " + e.getStatus());
            	logger.info("[极光推送]Error Code: " + e.getErrorCode());
            	logger.info("[极光推送]Error Message: " + e.getErrorMessage());
            }
     
            return result;
        }
        
        /**
         * 发送给所有用户(定时推送)
         * @param notification_title 通知内容标题
         * @param msg_title 消息内容标题
         * @param msg_content 消息内容
         * @param extrasparam 扩展字段
         * @param time 格式:yyyy-MM-dd HH:mm:ss
         * @return 0推送失败,1推送成功
         */
        public static int sendToAll2( String notification_title, String msg_title, String msg_content, String extrasparam, String time) {
            int result = 0;
            try {
                PushPayload pushPayload= JpushClientUtil2.buildPushObject_android_and_ios(notification_title,msg_title,msg_content,extrasparam);
                ScheduleResult scheduleResult=jPushClient.createSingleSchedule("测试", time, pushPayload);
                if(scheduleResult.getResponseCode()==200){
                    result=1;
                }
                logger.info("[极光推送]scheduleResult result is " + scheduleResult);
            } catch (APIConnectionException e) {
            	logger.error("[极光推送]Connection error. Should retry later. ", e);
            } catch (APIRequestException e) {
            	logger.error("[极光推送]Error response from JPush server. Should review and fix it. ", e);
            	logger.info("[极光推送]HTTP Status: " + e.getStatus());
            	logger.info("[极光推送]Error Code: " + e.getErrorCode());
            	logger.info("[极光推送]Error Message: " + e.getErrorMessage());
            }
     
            return result;
        }
     
     
        public static PushPayload buildPushObject_android_and_ios(String notification_title, String msg_title, String msg_content, String extrasparam) {
            return PushPayload.newBuilder()
                    .setPlatform(Platform.android_ios())
                    .setAudience(Audience.all())
                    .setNotification(Notification.newBuilder()
                            .setAlert(msg_content)
                            .addPlatformNotification(AndroidNotification.newBuilder()
                                    .setAlert(msg_content)
                                    .setTitle(notification_title)
                                    //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                    .addExtra("url",extrasparam)
                                    .build()
                            )
                            .addPlatformNotification(IosNotification.newBuilder()
                                    //传一个IosAlert对象,指定apns title、title、subtitle等
                                    .setAlert(msg_content)
                                    //直接传alert
                                    //此项是指定此推送的badge自动加1
                                    .incrBadge(1)
                                    //此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
                                    // 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
                                    .setSound("sound.caf")
                                    //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                    .addExtra("url",extrasparam)
                                    //此项说明此推送是一个background推送,想了解background看:http://docs.jpush.io/client/ios_tutorials/#ios-7-background-remote-notification
                                    // .setContentAvailable(true)
     
                                    .build()
                            )
                            .build()
                    )
                    //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                    // sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
                    // [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
                    .setMessage(Message.newBuilder()
                            .setMsgContent(msg_content)
                            .setTitle(msg_title)
                            .addExtra("url",extrasparam)
                            .build())
     
                    .setOptions(Options.newBuilder()
                            //此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                            .setApnsProduction(true)
                            //此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                            .setSendno(1)
                            //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                            .setTimeToLive(86400)
                            .build()
                    )
                    .build();
        }
     
        private static PushPayload buildPushObject_all_alias_alertWithTitle(List<String> alias,String notification_title, String msg_title, String msg_content, String extrasparam) {
            //创建一个IosAlert对象,可指定APNs的alert、title等字段
            //IosAlert iosAlert =  IosAlert.newBuilder().setTitleAndBody("title", "alert body").build();
     
            return PushPayload.newBuilder()
                    //指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
                    .setPlatform(Platform.all())
                    //指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
                    .setAudience(Audience.alias(alias))
    //                .setAudience(Audience.registrationId(registrationId))
                    //jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
                    .setNotification(Notification.newBuilder()
                            //指定当前推送的android通知
                            .addPlatformNotification(AndroidNotification.newBuilder()
                            			
                                    .setAlert(msg_content)
                                    .setTitle(notification_title)
                                    //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                    .addExtra("url",extrasparam)
     
                                    .build())
                            //指定当前推送的iOS通知
                            .addPlatformNotification(IosNotification.newBuilder()
                                    //传一个IosAlert对象,指定apns title、title、subtitle等
                                    .setAlert(msg_content)
                                    //直接传alert
                                    //此项是指定此推送的badge自动加1
                                    .incrBadge(1)
                                    //此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
                                    // 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
                                    .setSound("sound.caf")
                                    //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                    .addExtra("url",extrasparam)
                                    //此项说明此推送是一个background推送,想了解background看:http://docs.jpush.io/client/ios_tutorials/#ios-7-background-remote-notification
                                    //取消此注释,消息推送时ios将无法在锁屏情况接收
                                    // .setContentAvailable(true)
     
                                    .build())
     
     
                            .build())
                    //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                    // sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
                    // [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
                    .setMessage(Message.newBuilder()
     
                            .setMsgContent(msg_content)
     
                            .setTitle(msg_title)
     
                            .addExtra("url",extrasparam)
     
                            .build())
     
                    .setOptions(Options.newBuilder()
                            //此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                            .setApnsProduction(true)
                            //此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                            .setSendno(1)
                            //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天;
                            .setTimeToLive(86400)
     
                            .build())
     
                    .build();
     
        }
     
        private static PushPayload buildPushObject_android_all_alertWithTitle(String notification_title, String msg_title, String msg_content, String extrasparam) {
            return PushPayload.newBuilder()
                    //指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
                    .setPlatform(Platform.android())
                    //指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
                    .setAudience(Audience.all())
                    //jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
                    .setNotification(Notification.newBuilder()
                            //指定当前推送的android通知
                            .addPlatformNotification(AndroidNotification.newBuilder()
                                    .setAlert(msg_content)
                                    .setTitle(notification_title)
                                    //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                    .addExtra("url",extrasparam)
                                    .build())
                            .build()
                    )
                    //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                    // sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
                    // [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
                    .setMessage(Message.newBuilder()
                            .setMsgContent(msg_content)
                            .setTitle(msg_title)
                            .addExtra("url",extrasparam)
                            .build())
     
                    .setOptions(Options.newBuilder()
                            //此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                            .setApnsProduction(true)
                            //此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                            .setSendno(1)
                            //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                            .setTimeToLive(86400)
                            .build())
                    .build();
        }
     
        private static PushPayload buildPushObject_ios_all_alertWithTitle( String notification_title, String msg_title, String msg_content, String extrasparam) {
            return PushPayload.newBuilder()
                    //指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
                    .setPlatform(Platform.ios())
                    //指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
                    .setAudience(Audience.all())
                    //jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
                    .setNotification(Notification.newBuilder()
                            //指定当前推送的android通知
                            .addPlatformNotification(IosNotification.newBuilder()
                                    //传一个IosAlert对象,指定apns title、title、subtitle等
                                    .setAlert(msg_content)
                                    //直接传alert
                                    //此项是指定此推送的badge自动加1
                                    .incrBadge(1)
                                    //此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
                                    // 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
                                    .setSound("sound.caf")
                                    //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                    .addExtra("url",extrasparam)
                                    //此项说明此推送是一个background推送,想了解background看:http://docs.jpush.io/client/ios_tutorials/#ios-7-background-remote-notification
                                   // .setContentAvailable(true)
     
                                    .build())
                            .build()
                    )
                    //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                    // sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
                    // [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
                    .setMessage(Message.newBuilder()
                            .setMsgContent(msg_content)
                            .setTitle(msg_title)
                            .addExtra("url",extrasparam)
                            .build())
     
                    .setOptions(Options.newBuilder()
                            //此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                            .setApnsProduction(true)
                            //此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                            .setSendno(1)
                            //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                            .setTimeToLive(86400)
                            .build())
                    .build();
        }
     
    }

    推送成功返回:

     

    推送失败返回(大多的推送失败返回,都是1011找不到指定的目标用户):

     

    展开全文
  • 以前一直使用的极光的手动输入推送内容然后推送到客户端,今天遇到了推送频率比较高且比较有规律的内容,比如事实天气。这样就需要用我们自己的服务器来自动生成推送内容了。详细请看:...
  • (2)SockJS、Stomp、RabbitMQ... (4)可靠消息推送(Stomp持久化队列、客户端ACK确认机制); (5)Java原生、Stomp客户端实现(非浏览器客户端); (6)Websocket拦截器结合 Spring security、jwt token认证授权。
  • android通过极光服务器实现推送,android的客户端,java的服务器端
  • java调用apns推送的实现

    热门讨论 2014-07-02 09:48:41
    自己用java实现苹果的apns推送,调用压缩包的text文件里面的方法即可
  • 百度消息推送(最简单的Demo)

    千次下载 热门讨论 2014-02-24 11:21:19
    一个百度消息推送的最小demo,有兴趣的朋友可以看我的博文中相关部分:http://blog.csdn.net/dawanganban/
  • 本文介绍在Android中实现推送方式的基础知识及相关解决方案。推送功能在手机开发中应用的场景是越来起来了,不说别的,就我们手机上的新闻客户端就时不j时的推送过来新的消息,很方便的阅读最新的新闻信息。这种推送...

    本文介绍在Android中实现推送方式的基础知识及相关解决方案。推送功能在手机开发中应用的场景是越来起来了,不说别的,就我们手机上的新闻客户端就时不j时的推送过来新的消息,很方便的阅读最新的新闻信息。这种推送功能是好的一面,但是也会经常看到很多推送过来的垃圾信息,这就让我们感到厌烦了,关于这个我们就不能多说什么了,毕竟很多商家要做广告。本文就是来探讨下Android中实现推送功能的一些解决方案,也希望能够起到抛砖引玉的作用。^_^

     

      1.推送方式基础知识: 

      在移动互联网时代以前的手机,如果有事情发生需要通知用户,则会有一个窗口弹出,将告诉用户正在发生什么事情。可能是未接电话的提示,日历的提醒,或是一封新的彩信。推送功能最早是被用于Email中,用来提示我们新的信息。由于时代的发展和移动互联网的热潮,推送功能更加地普及,已经不再仅仅用在推送邮件了,更多地用在我们的APP中了。

     

      当我们开发需要和服务器交互的应用程序时,基本上都需要获取服务器端的数据,比如《地震应急通》就需要及时获取服务器上最新的地震信息。要获取服务器上不定时更新的信息,一般来说有两种方法:第一种是客户端使用Pull(拉)的方式,就是隔一段时间就去服务器上获取一下信息,看是否有更新的信息出现。第二种就是 服务器使用Push(推送)的方式,当服务器端有新信息了,则把最新的信息Push到客户端上。这样,客户端就能自动的接收到消息。 

     

      虽然Pull和Push两种方式都能实现获取服务器端更新信息的功能,但是明显来说Push方式比Pull方式更优越。因为Pull方式更费客户端的网络流量,更主要的是费电量,还需要我们的程序不停地去监测服务端的变化。  

     

      在开发Android和iPhone应用程序时,我们往往需要从服务器不定的向手机客户端即时推送各种通知消息。我们只需要在Android或IPhone的通知栏处向下一拉,就展开了Notification Panel,可以集中一览各种各样通知消息。目前IOS平台上已经有了比较简单的和完美的推送通知解决方案,我会在以后详细介绍IPhone中的解决方案,可是Android平台上实现起来却相对比较麻烦。

      最近利用几天的时间对Android的推送通知服务进行初步的研究,也希望能和大家共同探讨一下。

     

      2. 几种常见的解决方案实现原理:

      1)轮询(Pull)方式:应用程序应当阶段性的与服务器进行连接并查询是否有新的消息到达,你必须自己实现与服务器之间的通信,例如消息排队等。而且你还要考虑轮询的频率,如果太慢可能导致某些消息的延迟,如果太快,则会大量消耗网络带宽和电池。

     

      2)SMS(Push)方式:在Android平台上,你可以通过拦截SMS消息并且解析消息内容来了解服务器的意图,并获取其显示内容进行处理。这是一个不错的想法,我就见过采用这个方案的应用程序。这个方案的好处是,可以实现完全的实时操作。但是问题是这个方案的成本相对比较高,我们需要向移动公司缴纳相应的费用。我们目前很难找到免费的短消息发送网关来实现这种方案。

     

      3)持久连接(Push)方式:这个方案可以解决由轮询带来的性能问题,但是还是会消耗手机的电池。IOS平台的推送服务之所以工作的很好,是因为每一台手机仅仅保持一个与服务器之间的连接,事实上C2DM也是这么工作的。不过刚才也讲了,这个方案存在着很多的不足之处,就是我们很难在手机上实现一个可靠的服务,目前也无法与IOS平台的推送功能相比。

     

      Android操作系统允许在低内存情况下杀死系统服务,所以我们的推送通知服务很有可能就被操作系统Kill掉了。 轮询(Pull)方式和SMS(Push)方式这两个方案也存在明显的不足。至于持久连接(Push)方案也有不足,不过我们可以通过良好的设计来弥补,以便于让该方案可以有效的工作。毕竟,我们要知道GMail,GTalk以及GoogleVoice都可以实现实时更新的。

      

      3.第一种解决方案:C2DM云端推送功能。

      在Android手机平台上,Google提供了C2DM(Cloudto Device Messaging)服务,起初我就是准备采用这个服务来实现自己手机上的推送功能,并将其带入自己的项目中。 

     

      Android Cloud to Device Messaging (C2DM)是一个用来帮助开发者从服务器向Android应用程序发送数据的服务。该服务提供了一个简单的、轻量级的机制,允许服务器可以通知移动应用程序直接与服务器进行通信,以便于从服务器获取应用程序更新和用户数据。C2DM服务负责处理诸如消息排队等事务并向运行于目标设备上的应用程序分发这些消息。关于C2DM具体使用过程,大家可以去查阅相关的资料,在这里先让我们了解下大致方案情况。

     

      下面是C2DM操作过程示例图:

        

     

      但是经过一番研究发现,这个服务存在很大的问题:  

      1)C2DM内置于Android的2.2系统上,无法兼容老的1.6到2.1系统;

     

      2)C2DM需要依赖于Google官方提供的C2DM服务器,由于国内的网络环境,这个服务经常不可用,如果想要很好的使用,我们的App Server必须也在国外,这个恐怕不是每个开发者都能够实现的;

     

      3) 不像在iPhone中,他们把硬件系统集成在一块了。所以对于我们开发者来说,如果要在我们的应用程序中使用C2DM的推送功能,因为对于不同的这种硬件厂商平台,比如摩托罗拉、华为、中兴做一个手机,他们可能会把Google的这种服务去掉,尤其像在国内就很多这种,把Google这种原生的服务去掉。买了一些像什么山寨机或者是华为这种国产机,可能Google的服务就没有了。而像在国外出的那些可能会内置。

     

      有了上述几个方面的制约,导致我最终放弃了这个方案,不过我想利用另外一篇文章来详细的介绍C2DM的框架以及客户端和App Server的相应设置方法,可以作为学习资源让我们有个参考的资料。 即然C2DM无法满足我们的要求,那么我们就需要自己来实现Android手机客户端与App Server之间的通信协议,保证在App Server想向指定的Android设备发送消息时,Android设备能够及时的收到。

     

      4. 第二种解决方案:MQTT协议实现Android推送功能。

      采用MQTT协议实现Android推送功能也是一种解决方案。MQTT是一个轻量级的消息发布/订阅协议,它是实现基于手机客户端的消息推送服务器的理想解决方案。

      wmqtt.jar 是IBM提供的MQTT协议的实现。我们可以从这里https://github.com/tokudu/AndroidPushNotificationsDemo)下载该项目的实例代码,并且可以找到一个采用PHP书写的服务器端实现https://github.com/tokudu/PhpMQTTClient)。

     

      架构如下图所示:

          

     

      wmqtt.jar 是IBM提供的MQTT协议的实现。我们可以从如下站点下载http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006)它。我们可以将该jar包加入自己的Android应用程序中。

     

      5.第三种解决方案:RSMB实现推送功能。

      Really Small Message Broker (RSMB) ,他是一个简单的MQTT代理,同样由IBM提供,其查看地址是:http://www.alphaworks.ibm.com/tech/rsmb。缺省打开1883端口,应用程序当中,它负责接收来自服务器的消息并将其转发给指定的移动设备。

     

      SAM是一个针对MQTT写的PHP库。我们可以从这个http://pecl.php.net/package/sam/download/0.2.0地址下载它.

      send_mqtt.php是一个通过POST接收消息并且通过SAM将消息发送给RSMB的PHP脚本。 

     

      6. 第四种解决方案:XMPP协议实现Android推送功能。

      这是我希望在项目中采用的方案,因为目前它是开源的,对于其简单的推送功能它还是能够实现的。我们可以修改其源代码来适应我们的应用程序。

      事实上Google官方的C2DM服务器底层也是采用XMPP协议进行的封装。XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。关于XMPP协议我在上篇博文中已经介绍,大家可以参考下文章:http://www.cnblogs.com/hanyonglu/archive/2012/03/04/2378956.html

     

      androidpn是一个基于XMPP协议的java开源Android push notification实现,我会在以后的博文中详细介绍androidpn。它包含了完整的客户端和服务器端。经过源代码研究我发现,该服务器端基本是在另外一个开源工程openfire基础上修改实现的,不过比较郁闷的是androidpn的文档是由韩语写的,所以整个研究过程基本都是读源码。

     

      这是androidpn的项目主页:http://sourceforge.net/projects/androidpn/

     

      androidpn实现意图如下图所示:

      

     

      androidpn 客户端需要用到一个基于java的开源XMPP协议包asmack,这个包同样也是基于openfire下的另外一个开源项目smack,不过我们不需要自己编译,可以直接把androidpn客户端里面的asmack.jar拿来使用。客户端利用asmack中提供的XMPPConnection类与服 务器建立持久连接,并通过该连接进行用户注册和登录认证,同样也是通过这条连接,接收服务器发送的通知。

     

      androidpn服务器端也是java语言实现的,基于openfire开源工程,不过它的Web部分采用的是spring框架,这一点与 openfire是不同的。Androidpn服务器包含两个部分,一个是侦听在5222端口上的XMPP服务,负责与客户端的 XMPPConnection类进行通信,作用是用户注册和身份认证,并发送推送通知消息。另外一部分是Web服务器,采用一个轻量级的HTTP服务器, 负责接收用户的Web请求。服务器架构如下:

     

     

      最上层包含四个组成部分,分别是SessionManager,Auth Manager,PresenceManager以及Notification Manager。SessionManager负责管理客户端与服务器之间的会话,Auth Manager负责客户端用户认证管理,Presence Manager负责管理客户端用户的登录状态,NotificationManager负责实现服务器向客户端推送消息功能。

     

      这个解决方案的最大优势就是简单,我们不需要象C2DM那样依赖操作系统版本,也不会担心某一天Google服务器不可用。利用XMPP协议我们还可以进一步的对协议进行扩展,实现更为完善的功能。 采用这个方案,我们目前只能发送文字消息,不过对于推送来说一般足够了,因为我们不能指望通过推送得到所有的数据,一般情况下,利用推送只是告诉手机端服务器发生了某些改变,当客户端收到通知以后,应该主动到服务器获取最新的数据,这样才是推送服务的完整实现。 XMPP协议书相对来说还是比较简单的,值得我们进一步研究。

     

      但是在经过一段时间的测试,我发现关于androidpn也存在一些不足之处:

      1. 比如时间过长时,就再也收不到推送的信息了。

      2. 性能上也不够稳定。

        3. 如果将消息从服务器上推送出去,就不再管理了,不管消息是否成功到达客户端手机上。

     

      等等,总之,androidpn也有很多的缺点。如果我们要使用androidpn,则还需要做大量的工作。

      至于详细使用过程,我们会在下个博文中再给大家介绍。

     

      7.第五种解决方案:使用第三方平台。

      第三方平台有商用的也有免费的,我们可以根据实现情况使用。关于国内的第三方平台,我感觉目前比较不错的就是极光推送。关于极光推送目前是免费的,我们可以直接使用。关于详细情况,大家可以查看它的主页:http://www.jpush.cn/index.jsp,这里不再详细描述。

     

      关于MQTT的方案,国内最近出现基于 mqtt 的第三方解决方案 云巴 (http://yunba.io),据了解是原 极光推送 CTO 创办的,有兴趣的朋友可以研究下。

      

      关于国外的第三方平台我也见过几个:http://www.push-notification.org/。有兴趣的朋友可以查阅相关信息。使用第三方平台就需要使用别人的服务器,关于这点,你懂的。

     

      8.第六种解决方案:自己搭建一个推送平台。

      这不是一件轻松的工作,当然可以根据各自的需要采取合适的方案。

     

      好了,以上是关于在Android中实现推送方式的基础知识及相关解决方案。

     

      最后,希望转载的朋友能够尊重作者的劳动成果,加上转载地址:http://www.cnblogs.com/hanyonglu/archive/2012/03/04/2378971.html 谢谢。

     

      9. 各家之言

    本人做过类似于微信、米聊的手机上的聊天App,可以分享一下我的经验。
    微信是自己的协议,像米聊这些多数聊天App,刚开始都是使用 XMPP 开源方案。XMPP开源有很多可用的组件,客户端有 android 的 aSmack,服务器端有 Openfire(Java), Tigase(Java), ejabberd(Erlang) 等。整体来说,XMPP是个成熟的IM协议了,所以才有这么多可用的开源组件,这个协议也得到了 Google, Facebook, Apple 等大佬的支持。
    具体作法是:客户端与服务器端维持一个长连接,永远在线。服务器端消息才有可能及时地推送到客户端。其实,APNs, GCM 等,都是这个基本原理。
    MQTT本人没有正式用过,感觉应该是不合适聊天场景的。
    至于楼主提及的 androidpn,可以参考这篇文章看看:androidpn 作为Android推送方案存在的问题
    自己搭建环境存在它本身的很多问题。国内现在也用第三方的推送服务出来,并且是免费的,3分钟可以搞定集成。建议试试:极光推送 (http://jpush.cn)

     

    你搜索 XMPP IM 聊天等,应该就可以找到了一些资料了。都是公开、开源的。

     

    MQTT对于聊天应用应该是可以胜任的。我看到IBM的的Sametime web版应该使用了MQTT,使用感觉不错

     

    我可以给大家推荐一个我自己实现的消息推送方案,有源代码和github
    gonjay.github.io/blog/2014/03/03/android-receive-message-from-ruby-china-org/
    github:github.com/gonjay/rubychina4android
    是ruby-china的android客户端,而且这个消息推送的方案也支持桌面浏览器的消息提醒

     

    现在做的好的推送技术,应该是第三方推送商,开始以为极光不错,但是毕竟是免费的嘛,服务的话当然没有其他专注于推送服务的好,个推的话,有免费服务,如果想要好的推送效果也是要收费的,但毕竟这样用着保质保量,而且个推做推送技术应该是比较早的,积累的经验也很多,推送技术做的比较稳定先进,这是之前跟他们的一个工程师了解时得出来的。第三方免费的mobpush算是比较好用的了,之前有集成测试过的,效果很好,聚合通道的,到达率也还可以。DDPush (Dimension Door Push),任意门消息推送,是一款开源免费的单机千万级实时消息推送服务器,使用Java语言开发,具有简单、稳定、高性能、高容量等特点,适用于互联网、移动互联网、物联网、Android、智能设备、硬件设备等各种环境。

     

    10.更多参考

    https://www.cnblogs.com/itcqx/p/5641197.html

     

    展开全文
  • 1、项目需要,定时向所有在线用户推送一个广告或是推送一个通知之类的(比如服务器升级,请保存好手头工作之类的)。 2、相关环境 , Nginx、tomcat7、centos 6.5 3、项目框架,springMvc 4.0.6、layer
  • 物联网开发 第4讲 中移OneNET HTTP推送服务接入 在使用OneNET平台时,如果我们自己开发应用,基本上会有获取设备的上下线信息以及设备... 使用OneNET提供的数据推送的服务,实时推送设备上下线状态以及数据点...

    物联网开发 第4讲 中移OneNET HTTP推送服务接入

     

    在使用OneNET平台时,如果我们自己开发应用,基本上会有获取设备的上下线信息以及设备上传的数据点的需求。

     

    为了满足上述的需求,我们有以下两种方法:

    1.  使用OneNET的HTTP RESTful API轮询获取设备上下线状态以及数据点

    2. 使用OneNET提供的数据推送的服务,实时推送设备上下线状态以及数据点至自己的服务器。

     

    上面的两个方法,针对不同的应用场景,选择其中一种就可以了。

    比如我之前给孩子买过一个联网的机器人学习机,我用自己的微信通过商家的公众号与学习机绑定,学习机一旦开机,就会有一条“设备上线”的通知发到我的微信上。这种场景使用HTTP推送服务就再合适不过了。(我突然有个想法,后面实战的环节,我也可以模仿这个场景进行实战的演示)

     

    本篇我主要讲解OneNET平台的多协议产品如何使用HTTP推送服务。其中我在文章演示时的后台开发语言使用python(不懂python的朋友可以忽略python源码),大家可以用自己擅长的语言进行开发,毕竟步骤和思想都是一样的。

        我们先来看下OneNET官方关于HTTP推送的一些说明。

        OneNET平台提供数据推送功能,可以将平台作为客户端,将相关信息以HTTP/HTTPS请求的方式,发送给应用服务器。

    值得注意一点,其中的“相关信息”包括:

    • 设备新增数据点消息

    • 设备上下线消息

    • 设备对于下行命令的应答信息(仅限NB设备)

     

        OneNET推送服务提供数据过滤功能,用户可以以数据流模板为过滤条件,过滤掉例如设备的频繁的周期性上报等大量时间不敏感数据,只推送用户自己关心的实时性要求较高的数据,如下图所示。

                                          图 OneNET数据过滤框架(来自OneNET官方)

        当然,OneNET推送服务提供数据压缩的功能,用户可以设置数据量以及时间的压缩方式,将一定时间内的一定量的多包单信息报文,合并成为一包包含多条信息的json数据,可以大大减少应用服务器的处理压力,如下图所示

                                         图 OneNET数据压缩框架(来自OneNET官方)

     

     

       下面,我们直接进行演示,这里我基于MQTT协议的产品(其它协议使用方法是一样的)进行演示。

       如何创建产品和设备我就不多讲了,前面几个章节都讲的比较仔细。

       下图是我创建好的一个演示数据推送的MQTT产品:

    点击进入产品详情,创建一个新的设备,如下:

    点击OneNET控制台左侧列表的"数据推送\HTTP推送"

    消息推送的控制页面如下

    接下来,我们首先添加一条全局推送。

    添加全局推送就是要添加一个支持OneNET相应开发规则的URL,首先我们先准备一个能正常访问的URL,比如我这里的:

    http://152.136.74.228:5000/he/data/push/global

    一定要先确保该URL链接能 正常访问、正常访问、正常访问! 

     

    我此时的python源码为:

    from flask import Flask
    from flask import request
    import hashlib
    import base64
    
    app = Flask(__name__)
    
    
    # OneNET全局推送链接
    @app.route("/he/data/push/global", methods=['GET'])
    def he_data_push_global():
        return 'Hello IOT'
    
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', debug=True)

    点击"添加全局推送"

    填写相关的信息:

    URL:http://152.136.74.228:5000/he/data/push/global
    Token:20200321182801
    消息加密方式:明文模式
    数据推送:全部数据流

    然后点击"添加"按钮,此时OneNET会弹出如下信息:

    大概的意思是"鉴权失败,验证Token失败"。同时,当你点击"添加"按钮后,你可以看到你填写的URL会接收到如下一个请求:

    GET /he/data/push/global?msg=LeoTAq&signature=/7hXrr3IpM538Z1uHvxSlA==&nonce=B0k7pDoe

     

    可以看到URL后面携带了三个参数msg、signature、nonce,好了,这就要涉及到OneNET URL验证的问题了。

     

     

    在使用推送服务时,OneNET作为客户端,而用户的第三方应用是作为服务器,第三方应用需要支持URL验证以及数据接收两部分服务。

     

    用户在配置页面完成配置并点击“添加”时,OneNET平台会向填写URL地址发送HTTP GET请求进行URL验证,请求形式示例如下:

    http://url?msg=xxx&nonce=xxx&signature=xxx

    其中,url为用户在页面配置时填写的URL,nonce、msg、signature用于URL及token的验证

     

    token验证过程如下:

        1. 将配置页面中配置的token与URL中的nonce、msg的值计算MD5,并且编码为Base64字符串值

        2. 将上一步中Base64字符串值通过URL Decode计算后的值与请求参数signature的值进行对比,如果相等则表示token验证成功

        3. 如果token验证成功,返回msg参数值,表示URL验证通过。

     

    但是,还有一点,OneNET作了特别说明:

    如果用户不想验证token,可以选择跳过MD5计算过程,直接返回msg参数值

    也就是说,只要你的URL返回请求中的msg值,那就说明URL验证通过。我们先不对token进行校验,我们简单一点,直接获取并返回URL中的msg参数。流程跑通之后,我们再研究token验证的问题。

     

    如下,我修改了服务端的Python代码:

    @app.route("/he/data/push/global", methods=['GET'])
    def he_data_push_global():
        msg = request.args.get('msg') or None
        signature = request.args.get('signature') or None
        nonce = request.args.get('nonce') or None
        if not all([msg, signature, nonce]):
            return 'invalid parameter'
        return msg

        然后再点击"添加"按钮,

        此时可以看到,全局推送URL添加成功。

     

        然后我们再来看一下数据推送的内容。

       通常数据推送内容包括

    • 设备上下线信息

    • 设备新增数据点消息

     

       OneNET平台以HTTP POST请求形式向第三方平台URL地址推送数据,第三方平台接收到数据后需要返回 HTTP 200,否则OneNET会认为此次推送无效并重试。

     

       推送数据相关信息以JSON串的形式置于HTTP请求中的body部分,其中各个字段的含义如下:

     

    既然OneNET是以POST形式推送数据,那么我们就得在我们服务器指定的URL支持POST连接,我修改服务器端代码如下:

    @app.route("/he/data/push/global", methods=['GET', 'POST'])
    def he_data_push_global():
        if request.method == 'POST':
            print('**** Receive Post Data *****')
            print(request.data)
            return 'POST SUCCESS'
        msg = request.args.get('msg') or None
        signature = request.args.get('signature') or None
        nonce = request.args.get('nonce') or None
        if not all([msg, signature, nonce]):
            return 'invalid parameter'
        return msg

    服务端没有做什么内容,只是打印输出POST传递过来的Body数据。

     

    下面开始实验,我为了演示方便,写了一个多协议的设备模拟器,该软件的最新版本我会上传到QQ群940556740。

     

    例1:MQTT设备上线

    设备上线之后,服务器端接收到推送的数据:

    对比前面的表格,整理并分析其中的Body数据如下:

    {
      "msg":
        {
          "at":1585579321430,  //时间戳
          "login_type":7,    //设备登录协议类型 7-MQTT
          "type":2,          //消息类型  2:设备上下线消息
          "dev_id":589888962,  //设备ID
          "status":1        //设备上下线标识  1:设备上线
         },
      "msg_signature":"1FtJkDnewfBiKFJKKheJPA==",  //消息摘要
      "nonce":"w&INtJ9+"    //用于计算消息摘要的随机串
    }

     

    例2:MQTT设备下线

    设备下线之后,服务器端接收到推送的数据:

    {
      "msg":
        {
          "at":1585579700235,    //时间戳
          "login_type":7,      //设备登录协议类型 7-MQTT
          "type":2,            //消息类型  2:设备上下线消息
          "dev_id":589888962,    //设备ID
          "status":0      //设备上下线标识  1:设备下线
        },
        "msg_signature":"YPpafOSW1Byncd7xdXtF0Q==",  //消息摘要
        "nonce":"iSX$ZVVD"    //用于计算消息摘要的随机串
    }

     

    例3:MQTT设备新增数据点

    服务器端接收到推送的数据如下:

    {
      "msg":
        {
          "at":1585579995234,    //时间戳
          "type":1,       //消息类型  1:设备上下线消息
          "ds_id":"temperature",    //数据流名称
          "value":"12.34",        //数据点
          "dev_id":589888962      //设备ID
        },
        "msg_signature":"h1oeGIrbyreHf6S81qet9w==", //消息摘要
        "nonce":"Mal9%W-E"     //用于计算消息摘要的随机串
    }

    上面3个例子,实际演示了数据推送的内容。服务器端接收到推送的数据之后,可以根据不同的应用场景做后续的工作,比如开篇我提到的学习机,我们完全可以根据推送过来的设备上下线信息通过微信服务号的形式推送到客户微信客户端(后面一定要写个这样的实战项目)。

     

    其它的协议类型,可以用我的设备模拟器去验证

     

    文章讲到这里,最简单的数据推送的流程基本就演示完毕了。但是还有个地方需要再补充说明,就是URL验证部分。

     

       我在第3小节添加URL时并没有加入Token验证,这一节我就加上这个功能。

       OneNET的Token验证过程分为以下4步

    • 第1步,将URL添加时配置页面中配置的token与URL GET请求nonce、msg的值计算MD5

    • 第2步,将计算出的MD5值编码为Base64字符串值

    • 第3步,将编码后的Base64字符串值通过URL Decode编码

    • 第4步,将URL Decode编码后的值与请求参数signature的值进行对比,如果相等则表示token验证成功,返回msg值,否则返回其它自定义值。

     

    根据上面的步骤,我在服务器端修改python代码,如下:

    @app.route("/he/data/push/global", methods=['GET', 'POST'])
    def he_data_push_global():
        if request.method == 'POST':
            print('**** Receive Post Data *****')
            print(request.data)
            return 'POST SUCCESS'
        msg = request.args.get('msg') or None
        signature = request.args.get('signature') or None
        nonce = request.args.get('nonce') or None
        if not all([msg, signature, nonce]):
            return 'invalid parameter'
        token = '20200321182801'    # 这里是URL添加时填写的Token
        # 第1步 计算MD5
        params_str = token + nonce + msg
        md5 = hashlib.md5(params_str.encode('utf-8')).digest()
        # 第2步 编码为Base64字符串值
        b64_str = base64.b64encode(md5)
        # 第3步 将上一步中Base64字符串值通过URL Decode
        b64_str = b64_str.decode('utf-8')
        # 第4步 将URL Decode编码后的值与请求参数signature的值进行对比
        if signature == b64_str:
            return msg
        return 'invalid token'

    讲到这里,还有群组推送以及推送时的消息加密没有讲,读者请自行琢磨,如有不会,可以留言交流。

    码云地址:https://gitee.com/mybelief321/jliot

    展开全文
  • ios消息推送源码(含php服务端源码)

    热门讨论 2014-10-10 09:27:13
    ios消息推送源码,包括php服务端,做apns的朋友可以直接使用。xcode6.1 做的一个demo
  • 类库的主要功能是提供了基于网络传输层的长连接消息推送,包含服务端和客户端开发包,应用系统可以使用此类库,开发消息推送服务的程序;同时可以在JDK1.6以上的环境中编译使用,包括安卓操作系统。
  • 使用WCF实现服务器向客户端的信息推送,你说CSDN提示描述长度不够,写那么长的内容干什么呢?
  • ASp.net SignalR指定用户消息推送

    热门讨论 2016-04-20 15:55:02
    VS2010+SignalR1.1.3 根据用户id发送消息,类似流程推送
  • 极光推送集成厂商通道(java)

    千次阅读 2020-04-21 10:16:01
    极光推送后台开发文档:...以下封装的的推送工具类: package com.hpm.blog.jdpush; import java.util.Collection; import java.util.HashMap; import java.util.Map; im...

    极光推送后台开发文档:https://docs.jiguang.cn//jpush/server/push/rest_api_v3_push/

    跟安卓商量好,只能启用安卓端已经集成的厂商通道:

    以下封装的的推送工具类(工具类中也只能集成,安卓端已经集成的厂商通道——maps里面的厂商):

    package com.hpm.blog.jdpush;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    
    import cn.jiguang.common.resp.APIConnectionException;
    import cn.jiguang.common.resp.APIRequestException;
    import cn.jiguang.common.resp.DefaultResult;
    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.IosNotification;
    import cn.jpush.api.push.model.notification.Notification;
    import com.google.gson.JsonObject;
    
    
    /**
     * 极光推送消息
     *
     * */
    public class JPushUtil {
           private static String masterSecret = "";
           private static String appKey = "";
           private static JPushClient jPushClient = new JPushClient(masterSecret,appKey);
    
           /**
            * 推送给设备标识参数的用户
            * @param registrationId 设备标识
            * @param notification_title 通知内容标题
            * @param msg_title 消息内容标题
            * @param msg_content 消息内容
            * @param extrasparam 扩展字段
            * @return 0推送失败,1推送成功
            */
           public static int sendToRegistrationId( String registrationId,String notification_title, String msg_title, String msg_content, String extrasparam) {
               int result = 0;
               try {
                //ospush 表示强制厂商通道, jpush 表示强制极光通道,secondary_push 表示优先走极光,极光不在线再走厂商
                Map<String, String> map = new HashMap<String, String>();
                map.put("distribution","secondary_push");
                Map<String,Map<String, String>> maps = new HashMap<String,Map<String, String>>();
                maps.put("xiaomi",map);
                maps.put("huawei",map);
                maps.put("meizu",map);
                maps.put("oppo",map);
                maps.put("vivo",map);
       //       maps.put("fcm",map);
                   PushPayload pushPayload= JPushUtil.buildPushObject_all_registrationId_alertWithTitle(registrationId,notification_title,msg_title,msg_content,extrasparam,maps);
                   System.out.println(pushPayload);
                   PushResult pushResult=jPushClient.sendPush(pushPayload);
    
    /*             //ios推送vnps通知
                   Map map = new HashMap();
                map.put(msg_content,notification_title);
                map.put("sound",msg_title);
                jPushClient.sendIosNotificationWithAlias(msg_title,map,registrationId);*/
    
                   System.out.println(pushResult);
                   if(pushResult.getResponseCode()==200){
                       result=1;
                   }
               } catch (APIConnectionException e) {
                   e.printStackTrace();
    
               } catch (APIRequestException e) {
                   e.printStackTrace();
               }
    
                return result;
           }
           /**
            * 发送给所有安卓用户
            * @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 result = 0;
               try {
                   PushPayload pushPayload= JPushUtil.buildPushObject_android_all_alertWithTitle(notification_title,msg_title,msg_content,extrasparam);
                   System.out.println(pushPayload);
                   PushResult pushResult=jPushClient.sendPush(pushPayload);
                   System.out.println(pushResult);
                   if(pushResult.getResponseCode()==200){
                       result=1;
                   }
               } catch (Exception e) {
    
                   e.printStackTrace();
               }
    
                return result;
           }
    
           /**
            * 发送给所有IOS用户
            * @param notification_title 通知内容标题
            * @param msg_title 消息内容标题
            * @param msg_content 消息内容
            * @param extrasparam 扩展字段
            * @return 0推送失败,1推送成功
            */
           public static int sendToAllIos(String notification_title, String msg_title, String msg_content, String extrasparam) {
               int result = 0;
               try {
                   PushPayload pushPayload= JPushUtil.buildPushObject_ios_all_alertWithTitle(notification_title,msg_title,msg_content,extrasparam);
                   System.out.println(pushPayload);
                   PushResult pushResult=jPushClient.sendPush(pushPayload);
                   System.out.println(pushResult);
                   if(pushResult.getResponseCode()==200){
                       result=1;
                   }
               } catch (Exception e) {
    
                   e.printStackTrace();
               }
    
                return result;
           }
    
           /**
            * 发送给所有用户
            * @param notification_title 通知内容标题
            * @param msg_title 消息内容标题
            * @param msg_content 消息内容
            * @param extrasparam 扩展字段
            * @return 0推送失败,1推送成功
            */
           public static int sendToAll( String notification_title, String msg_title, String msg_content, String extrasparam) {
               int result = 0;
               try {
                //ospush 表示强制厂商通道, jpush 表示强制极光通道,secondary_push 表示优先走极光,极光不在线再走厂商
                Map<String, String> map = new HashMap<String, String>();
                map.put("distribution","secondary_push");
                Map<String,Map<String, String>> maps = new HashMap<String,Map<String, String>>();
                maps.put("xiaomi",map);
                maps.put("huawei",map);
                maps.put("meizu",map);
                maps.put("oppo",map);
                maps.put("vivo",map);
    /*          JsonObject json = new JsonObject();
                json.addProperty("distribution","secondary_push");
                JsonObject jsons = new JsonObject();
                jsons.add("xiaomi",json);
                jsons.add("huawei",json);
                jsons.add("meizu",json);
                jsons.add("fcm",json);
                jsons.add("oppo",json);
                jsons.add("vivo",json);*/
                   PushPayload pushPayload= JPushUtil.buildPushObject_android_and_ios(notification_title,msg_title,msg_content,extrasparam,maps);
                   System.out.println(pushPayload);
                   PushResult pushResult=jPushClient.sendPush(pushPayload);
                   System.out.println(pushResult);
                   if(pushResult.getResponseCode()==200){
                       result=1;
                   }
               } catch (Exception e) {
    
                   e.printStackTrace();
               }
    
               return result;
           }
           public static PushPayload buildPushObject_android_and_ios(String notification_title, String msg_title, String msg_content, String extrasparam,Map<String,Map<String, String>> maps) {
               return PushPayload.newBuilder()
                       .setPlatform(Platform.android_ios())
                       .setAudience(Audience.all())
                       .setNotification(Notification.newBuilder()
                               .setAlert(notification_title)
                               .addPlatformNotification(AndroidNotification.newBuilder()
                                       .setAlert(notification_title)
                                       .setTitle(msg_title)
                               .addCustom("uri_activity","com.weimi.accompany.push.OpenClickActivity")
                               .addCustom("uri_action","com.weimi.accompany.push.OpenClickActivity")
                                       //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                       .addExtra("androidNotification extras key",extrasparam)
                                       .build()
                               )
                               .addPlatformNotification(IosNotification.newBuilder()
                                       //传一个IosAlert对象,指定apns title、title、subtitle等
                                       .setAlert(notification_title)
                                       //直接传alert
                                       //此项是指定此推送的badge自动加1
                                       .incrBadge(0)
                                       //此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
                                       // 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
                                       .setSound("sound.caf")
                                       //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                       .addExtra("iosNotification extras key",extrasparam)
                                       //此项说明此推送是一个background推送
                                        .setContentAvailable(true)
    
                                       .build()
                               )
                               .build()
                       )
                       //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                       // sdk默认不做任何处理,不会有通知提示。
                       .setMessage(Message.newBuilder()
                               .setMsgContent(msg_content)
                               .setTitle(msg_title)
                               .addExtra("message extras key",extrasparam)
                               .build())
    
                       .setOptions(Options.newBuilder()
                               //此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                               .setApnsProduction(true)
                               //此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                               .setSendno(1)
                               //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                               .setTimeToLive(86400)
                         .setThirdPartyChannel(maps)
                               .build()
                       )
                       .build();
           }
           private static PushPayload buildPushObject_all_registrationId_alertWithTitle(String registrationId,String notification_title, String msg_title, String msg_content, String extrasparam,Map<String,Map<String, String>> maps) {
               System.out.println("----------buildPushObject_all_all_alert");
               //创建一个IosAlert对象,可指定APNs的alert、title等字段
               //IosAlert iosAlert =  IosAlert.newBuilder().setTitleAndBody("title", "alert body").build();
               return PushPayload.newBuilder()
                       //指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
                       .setPlatform(Platform.all())
                       //指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
                       .setAudience(Audience.registrationId(registrationId))  //设备标识
    //                 .setAudience(Audience.alias(registrationId)) //别名
                       //jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
                       .setNotification(Notification.newBuilder()
                               //指定当前推送的android通知
                               .addPlatformNotification(AndroidNotification.newBuilder()
                                       .setAlert(notification_title)//通知内容
                                       .setTitle(msg_title)//通知标题
                               .setBuilderId(3)//
                               .addCustom("uri_activity","com.weimi.accompany.push.OpenClickActivity")
                               .addCustom("uri_action","com.weimi.accompany.OpenClickActivity")
                                       //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                       .addExtra("androidNotification extras key",extrasparam)
    
                                       .build())
                               //指定当前推送的iOS通知
                               .addPlatformNotification(IosNotification.newBuilder()
                                       //传一个IosAlert对象,指定apns title、title、subtitle等
                                       .setAlert(notification_title)
                                       .setCategory(msg_content)
    
                                       //直接传alert
                                       //此项是指定此推送的badge自动加1
                                       .incrBadge(0)
                                       //此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
                                       // 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
                                       .setSound(msg_title)
                                       //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                       .addExtra("iosNotification extras key",extrasparam)
                                       //此项说明此推送是一个background推送
                                       //取消此注释,消息推送时ios将无法在锁屏情况接收
                                        .setContentAvailable(true)
    
                                       .build())
                               .build())
                       //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                       // sdk默认不做任何处理,不会有通知提示。
                       .setMessage(Message.newBuilder()
    
                               .setMsgContent(msg_content)
    
                               .setTitle(msg_title)
    
                               .addExtra("message extras key",extrasparam)
    
                               .build())
    
                       .setOptions(Options.newBuilder()
                               //此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                               .setApnsProduction(true)
                               //此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                               .setSendno(1)
                               //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天;
                               .setTimeToLive(86400)
                         .setThirdPartyChannel(maps)
                               .build())
                       .build();
    
           }
    
           private static PushPayload buildPushObject_android_all_alertWithTitle(String notification_title, String msg_title, String msg_content, String extrasparam) {
               System.out.println("----------buildPushObject_android_registrationId_alertWithTitle");
               return PushPayload.newBuilder()
                       //指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
                       .setPlatform(Platform.android())
                       //指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
                       .setAudience(Audience.all())
                       //jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
                       .setNotification(Notification.newBuilder()
                               //指定当前推送的android通知
                               .addPlatformNotification(AndroidNotification.newBuilder()
                                       .setAlert(notification_title)
                                       .setTitle(notification_title)
                                       //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                       .addExtra("androidNotification extras key",extrasparam)
                                       .build())
                               .build()
                       )
                       //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                       // sdk默认不做任何处理,不会有通知提示。
                       .setMessage(Message.newBuilder()
                               .setMsgContent(msg_content)
                               .setTitle(msg_title)
                               .addExtra("message extras key",extrasparam)
                               .build())
    
                       .setOptions(Options.newBuilder()
                               //此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                               .setApnsProduction(true)
                               //此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                               .setSendno(1)
                               //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                               .setTimeToLive(86400)
                               .build())
                       .build();
           }
    
           private static PushPayload buildPushObject_ios_all_alertWithTitle( String notification_title, String msg_title, String msg_content, String extrasparam) {
               System.out.println("----------buildPushObject_ios_registrationId_alertWithTitle");
               return PushPayload.newBuilder()
                       //指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
                       .setPlatform(Platform.ios())
                       //指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
                       .setAudience(Audience.all())
                       //jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
                       .setNotification(Notification.newBuilder()
                               //指定当前推送的android通知
                               .addPlatformNotification(IosNotification.newBuilder()
                                       //传一个IosAlert对象,指定apns title、title、subtitle等
                                       .setAlert(notification_title)
                                       //直接传alert
                                       //此项是指定此推送的badge自动加1
                                       .incrBadge(0)
                                       //此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
                                       // 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
                                       .setSound("sound.caf")
                                       //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                       .addExtra("iosNotification extras key",extrasparam)
                                       //此项说明此推送是一个background推送
                                       .setContentAvailable(true)
    
                                       .build())
                               .build()
                       )
                       //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                       // sdk默认不做任何处理,不会有通知提示。
                       .setMessage(Message.newBuilder()
                               .setMsgContent(msg_content)
                               .setTitle(msg_title)
                               .addExtra("message extras key",extrasparam)
                               .build())
    
                       .setOptions(Options.newBuilder()
                               //此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                               .setApnsProduction(true)
                               //此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                               .setSendno(1)
                               //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                               .setTimeToLive(86400)
                               .build())
                       .build();
           }
    
    
    
    
           public static int sendToaliasList( Collection<String> aliases,String notification_title, String msg_title, String msg_content, String extrasparam) {
               int result = 0;
               try {
                //ospush 表示强制厂商通道, jpush 表示强制极光通道,secondary_push 表示优先走极光,极光不在线再走厂商
                Map<String, String> map = new HashMap<String, String>();
                map.put("distribution","secondary_push");
                Map<String,Map<String, String>> maps = new HashMap<String,Map<String, String>>();
                maps.put("xiaomi",map);
                maps.put("huawei",map);
                maps.put("meizu",map);
                maps.put("oppo",map);
                maps.put("vivo",map);
       //       maps.put("fcm",map);
                   PushPayload pushPayload= JPushUtil.buildPushObject_all_sendToaliasList_alertWithTitle(aliases,notification_title,msg_title,msg_content,extrasparam,maps);
                   System.out.println(pushPayload);
                   PushResult pushResult=jPushClient.sendPush(pushPayload);
                   System.out.println(pushResult);
                   if(pushResult.getResponseCode()==200){
                       result=1;
                   }
               } catch (APIConnectionException e) {
                   e.printStackTrace();
    
               } catch (APIRequestException e) {
                   e.printStackTrace();
               }
    
                return result;
           }
           private static PushPayload buildPushObject_all_sendToaliasList_alertWithTitle(Collection<String> aliases,String notification_title, String msg_title, String msg_content, String extrasparam,Map<String,Map<String, String>> maps) {
    
               System.out.println("----------buildPushObject_all_all_alert");
               //创建一个IosAlert对象,可指定APNs的alert、title等字段
               //IosAlert iosAlert =  IosAlert.newBuilder().setTitleAndBody("title", "alert body").build();
               return PushPayload.newBuilder()
                       //指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
                       .setPlatform(Platform.all())
                       //指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
                       .setAudience(Audience.registrationId(aliases))
    //                 .setAudience(Audience.alias(aliases))
                       //jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
                       .setNotification(Notification.newBuilder()
                               //指定当前推送的android通知
                               .addPlatformNotification(AndroidNotification.newBuilder()
                                       .setAlert(notification_title)
                                       .setTitle(msg_title)
                                       //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                               .addCustom("uri_activity","com.weimi.accompany.push.OpenClickActivity")
                               .addCustom("uri_action","com.weimi.accompany.OpenClickActivity")
                                       .addExtra("androidNotification extras key",extrasparam)
    
                                       .build())
                               //指定当前推送的iOS通知
                               .addPlatformNotification(IosNotification.newBuilder()
                                       //传一个IosAlert对象,指定apns title、title、subtitle等
                                       .setAlert(notification_title)
                                       .setCategory(msg_content)
    
                                       //直接传alert
                                       //此项是指定此推送的badge自动加1
                                       .incrBadge(0)
                                       //此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
                                       // 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
                                       .setSound(msg_title)
                                       //此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                                       .addExtra("iosNotification extras key",extrasparam)
                                       //此项说明此推送是一个background推送
                                       //取消此注释,消息推送时ios将无法在锁屏情况接收
                                       // .setContentAvailable(true)
    
                                       .build())
                               .build())
                       //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                       // sdk默认不做任何处理,不会有通知提示。
                       .setMessage(Message.newBuilder()
    
                               .setMsgContent(msg_content)
    
                               .setTitle(msg_title)
    
                               .addExtra("message extras key",extrasparam)
    
                               .build())
    
                       .setOptions(Options.newBuilder()
                               //此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                               .setApnsProduction(true)
                               //此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                               .setSendno(1)
                               //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天;
                               .setTimeToLive(86400)
                         .setThirdPartyChannel(maps)
                               .build())
                       .build();
    
           }
       /**
        * 推送给设备标识参数的用户
        * @param alian 设备标识
        */
       public static int deleteByalian( String alian) {
          int result = 0;
          try {
             DefaultResult pushResult = jPushClient.deleteAlias(alian,null);   //删除别名
    //       DefaultResult pushResult = jPushClient.updateDeviceTagAlias("101d855909dbb0bb5b0",true,true); //设置空别名
    //       DefaultResult pushResult = jPushClient.updateDeviceTagAlias("170976fa8a02ddf2442",alian,null, null);//绑定别名
             System.out.println(pushResult);
             if(pushResult.getResponseCode()==200){
                result=1;
             }
          } catch (APIConnectionException e) {
             e.printStackTrace();
    
          } catch (APIRequestException e) {
             e.printStackTrace();
          }
    
          return result;
       }
           public static void main(String[] args){
             if(JPushUtil.sendToAllIos("testIos","testIos","this is a ios Dev test","")==1){
                 System.out.println("success");
             }
            }
    
    }

    直接调用这个类的静态方法即可,也可以参照开发文档,增加方法中的功能字段

    展开全文
  • SpringBoot整合极光推送

    万次阅读 热门讨论 2019-06-14 21:52:36
    极光推送代码 1. maven依赖 <!--极光推送--> <dependency> <groupId>cn.jpush.api</groupId> <artifactId>jpush-client</artifactId> <version>3.2.9</version...
  • java SDK服务端推送 --极光推送(JPush)

    千次阅读 热门讨论 2019-01-21 19:06:38
    消息推送在APP应用中越来越普遍,来记录一下项目中用到的一种推送方式,对于Andriod它并没有自己的原生推送机制,一种简单的推送方式是采用第三方推送服务的方式,即通过嵌入SDK使用第三方提供的推送服务,主流的有...
  • android手机摄像头推送至RTMP服务器

    热门讨论 2014-08-15 13:30:10
    -将android手机模拟为监控摄像头,推送视频流至RTMP服务器。 -不使用flash,APP工作时,本机也无需安装flash。 -兼容大部分手机,一般2.3.3以上,ARM V7架构即可。 -默认分辨率352x288,特定场合下,640x480也能...
  • Android 多厂商推送集成

    千次阅读 2019-09-19 10:25:44
    好不容易集成完了个推的推送 SDK,美滋滋的准备划一会儿水,鸟哥吩咐为了保证应用杀死后也可以接收到推送,并且降低服务端的维护多渠道的开发成本,还得集成下个推的多厂商渠道。等等!!!什么是多厂商?! 我没...
  • //此字段是给开发者自己给推送编号,方便推送者分辨推送记录 .setSendno(1) //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒 .setTimeToLive(86400) ....
  • 个推消息推送demo

    2016-05-18 09:48:41
    1、个推推送透传消息的实现 2、消息在通知栏中显示 3、点击通知栏进入相应页面 4、工程目录结构介绍及效果展示
  • MQTT推送简单例子服务端java代码实现

    千次下载 热门讨论 2014-04-25 13:53:04
    如果想做这个例子需要自己用电脑建一个wifi,手机连上这个wifi,代码中要改几个个地方 1 android服务里有几个MQTT_HOST是ip地址改成自己wifi的ip; 2 服务端的publish方法是用来发送的,第一个参数是客户端id ...
  • 微信公众帐号主动发送消息给用户,asp.net版本
  • 极光推送之java后台封装REST API

    千次阅读 2018-12-13 15:50:40
    1 什么是推送? 这个看图效果最好请直接看下图: 我们手机经常会收到如上图弹框消息,我们今天说的dfsdf啊
  • uni-app消息推送方案

    万次阅读 热门讨论 2019-11-06 01:13:40
    uni-app是支持消息推送的,参考如下文档: UniPush介绍 UniPush使用指南 UniPush开通指南 如何自定义推送通知的图标? 在 uni-app 中使用 UniPush 二、效果 开源项目uniapp-admin 三、需求 不同角色的用户登陆App,...
  • 说Android端外推送比较烦,实际有两层意思:首先是说实现上比较麻烦,至今业界也没有找到一种完美的解决方案,Android程序员通常需要同时集成多家推送平台(如果有自己的端内推送,还要考虑与端内推送的配合);...
  • 最近需要开发微信和小程序的推送功能,需要用java后台实现推送,自己本身java和小程序都做,所以就自己动手实现下小程序的模版推送功能推送。 实现思路 1 小程序获取用户openid,收集formid传给java...
  • 今天来带大家学习下微信模版消息推送。 先看效果图: 核心代码只有下面几行,即可轻松实现微信模版消息推送 //1,配置 WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage(); wxStorage....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 545,751
精华内容 218,300
关键字:

推送