u-push java怎么springmvc集成pushlet

一下飞机就有亲切感,“我真的有记忆,来过这里。”
留下三个未成年孩子和一对需要长期吃药的古稀老人。
声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
(点击上方公众号,可快速关注)
  来源: hengyunabc
  链接: http://blog.csdn.net/u/article/details/
  一、SpringMVC
  http://blog.csdn.net/evankaka/article/details/
  Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
  模型(Model )封装了应用程序的数据和一般他们会组成的POJO。
  视图(View)是负责呈现模型数据和一般它生成的HTML输出,客户端的浏览器能够解释。
  控制器(Controller )负责处理用户的请求,并建立适当的模型,并把它传递给视图渲染。
  Spring的web模型 C 视图 C 控制器(MVC)框架是围绕着处理所有的HTTP请求和响应的DispatcherServlet的设计。
  Spring Web MVC处理请求的流程
  这里写图片描述
  具体执行步骤如下:
  1、 首先用户发送请求――――&前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图2-1中的1、2步骤;
  2、 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);图2-1中的3、4、5步骤;
  3、 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图2-1中的步骤6、7;
  4、 前端控制器再次收回控制权,将响应返回给用户,图2-1中的步骤8;至此整个结束。
  二、Spring
  http://blog.csdn.net/cainiaowys/article/details/7107925
  2.1、IOC容器:/linjiqin/archive//3407126.html
  IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中new相关的对象,应用程序由IOC容器进行组装。在Spring中BeanFactory是IOC容器的实际代表者。
  2.2、AOP:http://blog.csdn.net/moreevan/article/details/
  简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系
  AOP用来封装横切关注点,具体可以在下面的场景中使用:
  Authentication 权限
  Caching 缓存
  Context passing 内容传递
  Error handling 错误处理
  Lazy loading 懒加载
  Debugging 调试
  logging, tracing, profiling and monitoring 记录跟踪 优化 校准
  Performance optimization 性能优化
  Persistence 持久化
  Resource pooling 资源池
  Synchronization 同步
  Transactions 事务
  三、Mybatis
  http://blog.csdn.net/u/article/details/
  MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
  总体流程:
  (1)加载配置并初始化
  触发条件:加载配置文件
  将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
  (2)接收调用请求
  触发条件:调用Mybatis提供的API
  传入参数:为SQL的ID和传入参数对象
  处理过程:将请求传递给下层的请求处理层进行处理。
  (3)处理操作请求 触发条件:API接口层传递请求过来
  传入参数:为SQL的ID和传入参数对象
  处理过程:
  (A)根据SQL的ID查找对应的MappedStatement对象。
  (B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
  (C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
  (D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
  (E)释放连接资源。
  (4)返回处理结果将最终的处理结果返回。
  MyBatis 最强大的特性之一就是它的动态语句功能。如果您以前有使用JDBC或者类似框架的经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在columns列后面省略一个逗号等。动态语句能够完全解决掉这些痛苦。
  四、Dubbo
  http://blog.csdn.net/u/article/details/
  Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC(远程过程调用协议)远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架。
  1、透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
  2、软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
  3、 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
  节点角色说明:
  Provider: 暴露服务的服务提供方。
  Consumer: 调用远程服务的服务消费方。
  Registry: 服务注册与发现的注册中心。
  Monitor: 统计服务的调用次调和调用时间的监控中心。
  Container: 服务运行容器。
  五、Maven
  http://blog.csdn.net/u/article/details/
  Maven这个个项目管理和构建自动化工具,越来越多的开发人员使用它来管理项目中的jar包。但是对于我们程序员来说,我们最关心的是它的项目构建功能。
  六、RabbitMQ
  http://blog.csdn.net/u/article/category/6061896
  消息队列一般是在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。
  RabbitMQ是用Erlang实现的一个高并发高可靠AMQP消息队列服务器。
  Erlang是一门动态类型的函数式编程语言。对应到Erlang里,每个Actor对应着一个Erlang进程,进程之间通过消息传递进行通信。相比共享内存,进程间通过消息传递来通信带来的直接好处就是消除了直接的锁开销(不考虑Erlang虚拟机底层实现中的锁应用)。
  AMQP(Advanced Message Queue Protocol)定义了一种消息系统规范。这个规范描述了在一个分布式的系统中各个子系统如何通过消息交互。
  七、Log4j
  http://blog.csdn.net/u/article/category/6045728
  日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。
  八、Ehcache
  http://blog.csdn.net/u/article/category/6066337
  EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。
  优点:
  1、 快速
  2、 简单
  3、 多种缓存策略
  4、缓存数据有两级:内存和磁盘,因此无需担心容量问题
  5、 缓存数据会在虚拟机重启的过程中写入磁盘
  6、可以通过RMI、可插入API等方式进行分布式缓存
  7、 具有缓存和缓存管理器的侦听接口
  8、支持多缓存管理器实例,以及一个实例的多个缓存区域
  9、提供Hibernate的缓存实现
  缺点:
  1、使用磁盘Cache的时候非常占用磁盘空间:这是因为DiskCache的算法简单,该算法简单也导致Cache的效率非常高。它只是对元素直接追加存储。因此搜索元素的时候非常的快。如果使用DiskCache的,在很频繁的应用中,很快磁盘会满。
  2、 不能保证数据的安全:当突然kill掉java的时候,可能会产生冲突,EhCache的解决方法是如果文件冲突了,则重建cache。这对于Cache数据需要保存的时候可能不利。当然,Cache只是简单的加速,而不能保证数据的安全。如果想保证数据的存储安全,可以使用Bekeley DB Java Edition版本。这是个嵌入式数据库。可以确保存储安全和空间的利用率。
  九、Redis
  http://blog.csdn.net/u/article/category/6067864
  redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set C有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
  Redis数据库完全在内存中,使用磁盘仅用于持久性。相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。Redis可以将数据复制到任意数量的从服务器。
  1.2、Redis优点:
  (1)异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
  (2)支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。
  (3)操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
  (4)多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。
  1.3、Redis缺点:
  (1)单线程
  (2)耗内存
  十、Shiro
  http://blog.csdn.net/u/article/details/
  Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证,授权,企业会话管理和加密等。Shiro的具体功能点如下:
  (1)身份认证/登录,验证用户是不是拥有相应的身份;
  (2)授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
  (3)会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
  (4)加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
  (5)Web支持,可以非常容易的集成到Web环境;
  Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
  (6)shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
  (7)提供测试支持;
  (8)允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
  (9)记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
  文字描述可能并不能让猿友们完全理解具体功能的意思。下面我们以登录验证为例,向猿友们介绍Shiro的使用。至于其他功能点,猿友们用到的时候再去深究其用法也不迟。
  十一、设计模式
  这个算不上框架,可自行忽略,不过博主认为设计模式的思想很有必要了解一下。
  http://blog.csdn.net/u/article/details/
  http://blog.csdn.net/u/article/details/
  http://blog.csdn.net/u/article/details/
  思想:
  开闭原则:开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码。
  针对接口编程,真对接口编程,依赖于抽象而不依赖于具体。
  尽量使用合成/聚合的方式,而不是使用继承。
  一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
  使用多个隔离的接口,比使用单个接口要好。
  里氏代换原则:(1)子类的能力必须大于等于父类,即父类可以使用的方法,子类都可以使用。(2)返回值也是同样的道理。假设一个父类方法返回一个List,子类返回一个ArrayList,这当然可以。如果父类方法返回一个ArrayList,子类返回一个List,就说不通了。这里子类返回值的能力是比父类小的。(3)还有抛出异常的情况。任何子类方法可以声明抛出父类方法声明异常的子类。
  而不能声明抛出父类没有声明的异常。
【今日微信公号推荐↓】
更多推荐请看《》
  其中推荐了包括技术、设计、极客和IT相亲相关的热门公众号。技术涵盖:Python、Web前端、Java、安卓、iOS、PHP、C/C++、.NET、Linux、数据库、运维、大数据、算法、IT职场等。点击《》,发现精彩!
  点击阅读原文,了解野狗
欢迎举报抄袭、转载、暴力色情及含有欺诈和虚假信息的不良文章。
请先登录再操作
请先登录再操作
微信扫一扫分享至朋友圈
搜狐公众平台官方账号
生活时尚&搭配博主 /生活时尚自媒体 /时尚类书籍作者
搜狐网教育频道官方账号
全球最大华文占星网站-专业研究星座命理及测算服务机构
主演:黄晓明/陈乔恩/乔任梁/谢君豪/吕佳容/戚迹
主演:陈晓/陈妍希/张馨予/杨明娜/毛晓彤/孙耀琦
主演:陈键锋/李依晓/张迪/郑亦桐/张明明/何彦霓
主演:尚格?云顿/乔?弗拉尼甘/Bianca Bree
主演:艾斯?库珀/ 查宁?塔图姆/ 乔纳?希尔
baby14岁写真曝光
李冰冰向成龙撒娇争宠
李湘遭闺蜜曝光旧爱
美女模特教老板走秀
曝搬砖男神奇葩择偶观
柳岩被迫成赚钱工具
大屁小P虐心恋
匆匆那年大结局
乔杉遭粉丝骚扰
男闺蜜的尴尬初夜
客服热线:86-10-
客服邮箱:上篇介绍了 Spring-data-jpa一些使用方法,都是基于mysql数据库来讲解的,但是在实际项目中,由于访问量的不断增大,数据库的压力会越来越大,这时候类似于mysql的数据库往往只是为了兜底或者在降级时才会有查询操作,大部分的读操作都会集中在缓存或者像elasticsearch这种全文搜索引擎,本篇主要介绍一下如何在SpringBoot中使用Redis,后续会介绍如何集成elasticsearch
1、添加Redis起步依赖
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-redis&/artifactId&
&/dependency&
2、添加Redis相关配置
host: localhost
port: 6379
max-idle: 100
min-idle: 1
max-active: 1000
max-wait: -1
3、编写Redis配置类
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
* 生成key的策略
public KeyGenerator keyGenerator {
return new KeyGenerator {
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringB
sb.append(target.getClass.getName);
sb.append(method.getName);
for (Object obj : params) {
sb.append(obj.toString);
return sb.toS
* 管理缓存
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
* RedisTemplate配置
public RedisTemplate&String, String& redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectM
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesS
4、编写Redis操作相关Service
public class RedisService {
@Autowired
private RedisTemplate redisT
* 写入缓存
* @param key
* @param value
public boolean set(final String key, Object value) {
boolean result =
ValueOperations&Serializable, Object& operations = redisTemplate.opsForV
operations.set(key, value);
} catch (Exception e) {
e.printStackT
* 写入缓存设置时效时间
* @param key
* @param value
public boolean set(final String key, Object value, Long expireTime) {
boolean result =
ValueOperations&Serializable, Object& operations = redisTemplate.opsForV
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackT
* 批量删除对应的value
* @param keys
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
* 批量删除key
* @param pattern
public void removePattern(final String pattern) {
Set&Serializable& keys = redisTemplate.keys(pattern);
if (keys.size & 0)
redisTemplate.delete(keys);
* 删除对应的value
* @param key
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
* 判断缓存中是否有对应的value
* @param key
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
* 读取缓存
* @param key
public Object get(final String key) {
Object result =
ValueOperations&Serializable, Object& operations = redisTemplate.opsForV
result = operations.get(key);
* 哈希 添加
* @param key
* @param hashKey
* @param value
public void hmSet(String key, Object hashKey, Object value){
HashOperations&String, Object, Object&
hash = redisTemplate.opsForH
hash.put(key,hashKey,value);
* 哈希获取数据
* @param key
* @param hashKey
public Object hmGet(String key, Object hashKey){
HashOperations&String, Object, Object&
hash = redisTemplate.opsForH
return hash.get(key,hashKey);
* 列表添加
* @param k
* @param v
public void lPush(String k,Object v){
ListOperations&String, Object& list = redisTemplate.opsForL
list.rightPush(k,v);
* 列表获取
* @param k
* @param l
* @param l1
public List&Object& lRange(String k, long l, long l1){
ListOperations&String, Object& list = redisTemplate.opsForL
return list.range(k,l,l1);
* 集合添加
* @param key
* @param value
public void add(String key,Object value){
SetOperations&String, Object& set = redisTemplate.opsForS
set.add(key,value);
* 集合获取
* @param key
public Set&Object& setMembers(String key){
SetOperations&String, Object& set = redisTemplate.opsForS
return set.members(key);
* 有序集合添加
* @param key
* @param value
* @param scoure
public void zAdd(String key,Object value,double scoure){
ZSetOperations&String, Object& zset = redisTemplate.opsForZS
zset.add(key,value,scoure);
* 有序集合获取
* @param key
* @param scoure
* @param scoure1
public Set&Object& rangeByScore(String key,double scoure,double scoure1){
ZSetOperations&String, Object& zset = redisTemplate.opsForZS
return zset.rangeByScore(key, scoure, scoure1);
5、写一个controller打印测试一下
@RestController
@RequestMapping(value=&/redis&)
public class redisTestController {
@Autowired
private RedisService redisS
@RequestMapping(value = &/test&, method = {RequestMethod.GET, RequestMethod.POST})
public String redisTest{
StringBuffer sb = new StringB
redisService.set(&str&, &str&);
sb.append(&str=&).append(redisService.get(&str&).toString).append(&,&);
redisService.hmSet(&hmset&,&key&,&val&);
sb.append(&hmset=&).append(redisService.hmGet(&hmset&,&key&)).append(&,&);
redisService.lPush(&list&,&val&);
sb.append(&list=&).append(redisService.lRange(&list&,0,1).toString).append(&,&);
redisService.add(&set&,&val&);
sb.append(&set=&).append(redisService.setMembers(&set&).toString).append(&,&);
redisService.zAdd(&zset&,&val1&,1);
redisService.zAdd(&zset&,&val2&,2);
sb.append(&zset=&).append(redisService.rangeByScore(&zset&,1,2)).append(&,&);
return sb.toS
我们在浏览器中输入http://localhost:8080/redis/test,显示一下页面,ok!Redis集成完成,是不是很简单呢!!!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:104983次
积分:3102
积分:3102
排名:第9319名
原创:24篇
转载:1065篇
评论:32条
(33)(59)(244)(216)(266)(102)(56)(55)(54)(7)> 消息推送 > 消息推送android文档 > 2.8.1 SDK集成指南
版本号:V2.8.1
说明:如需参考V2.6.0sdk集成文档,请参考
友盟消息推送组件帮助您实时的推送消息给用户。
版本更新:1、升级wire版本。
2、完善对android 6.0系统的适配。
3、性能优化。
消息推送SDK 支持Android 2.2 (API 8)及以上系统。建议在编译和混淆时引用最新版本Android SDK (17+),因为Message SDK 条件使用了一些android-8 以上的API。对于Android 2.2 以下的系统, 消息推送组件不工作,但不影响应用本身功能的正常使用。
集成SDK之前, 请在
创建应用,获取应用对应的AppKey和Umeng Message Secret。
注意即使应用名称相同,android版和IOS版仍是属于不同平台的两个应用,无法共用一个Appkey,需要分开注册。
感受推送(玩转DEMO)
1、使用友盟推送demo时,请用demo的包名注册一个新应用。
2、使用eclipse导入demo时,请把下载的eclipselibs目录下的okio-1.6.0.jar、wire-runtime-2.1.2.jar两个文件拷贝到demo的Pushlib的libs目录下,并把Pushlib目录下的AndroidManifest.xml里面的${applicationId}替换成demo的包名com.umeng.message.example (总共有3处需要替换,请注意)。
点击“open an existing android studio project”, 打开demo
替换AppKey和Umeng Message Secret
用添加应用时获得的AppKey和Umeng Message Secret替换掉Demo中默认的AppKey和Umeng Message Secret。
将Demo的apk包安装到测试设备上并打开。
demo效果如下图:
给该设备发送测试消息。
消息推送SDK 不支持在QEMU模拟器上调试,调试时请尽量使用真机。
PushSDK的引入
注意:v2.8.1版本SDK是采用module依赖的形式。请不要把module拆开,否则将会导致SDK不能正常使用。
Android Studio开发工具
把下载的SDK里面的PushSDK当做Module导入自己的项目,如下图所示:
在自己项目的build.gradle里面一定要配置applicationId,PushSDK下的AndroidManifest.xml里面的${applicationId}会引用到applicationId。如下所示:
defaultConfig {
applicationId "应用的包名"
minSdkVersion 8
targetSdkVersion 22
如果是android6.0以上的api编译,需要在PushSDK的build.gradle文件的android{}块内添加useLibrary 'org.apache.http.legacy',并把compileSdkVersion的版本号改为23。
主Module依赖PushSDK,在主module的build.gradle文件的dependencies下添加compile project(':PushSDK')。
如果okio-1.6.0.jar、wire-runtime-2.1.2.jar这两个文件从jcenter上下载失败,可以把官网下载的文件夹中的eclipselibs目录下的okio-1.6.0.jar、wire-runtime-2.1.2.jar这两个文件拷贝到工程的libs目录下,使用本地依赖的方式对这两个jar进行依赖,同时将PushSDK目录下的build.gradle文件中的compile 'com.squareup.okio:okio:1.6.0'、compile 'com.squareup.wire:wire-runtime:2.1.2'注释掉。
Android Plugin Version(com.android.tools.build:gradle)推荐使用1.5.0及以上版本,使用过旧的版本可能由于编译问题导致无法获取device token。
Eclipse开发工具
把下载的SDK里面的PushSDK当做library引用导入自己的项目。
把AndroidManifest.xml里面的${applicationId}替换成为自己项目的包名。
把下载的eclipselibs目录下的okio-1.6.0.jar、wire-runtime-2.1.2.jar这两个文件拷贝到PushSDK的libs目录下。
在自己项目的目录下找到project.properties,在里面加入manifestmerger.enabled=true。
如果是android6.0以上的api编译,把SDK目录下的libs/里面的org.apache.http.legacy.jar拷贝到PushSDK的libs目录,然后加入buildpath里面
ADT插件推荐使用23.0.2及以上版本,同时保证主工程的minSdkVersion和targetSdkVersion与PushSDK的minSdkVersion和targetSdkVersion一致,使用过旧的ADT插件可能导致合并清单(manifestmerger.enabled=true)出错。
添加AppKey & Umeng Message Secret
在项目工程的AndroidManifest.xml中的&Application&标签下添加:
&meta-data
android:name="UMENG_APPKEY"
android:value="xxxxxxxxxxxxxxxxxxxxxxxxxxxx" &
&/meta-data&
&meta-data
android:name="UMENG_MESSAGE_SECRET"
android:value="xxxxxxxxxxxxxxxxxxxxxxxxxxxx" &
&/meta-data&
把上述的umeng_appkey和umengmessage_secret修改为和自己App对应的值
请在创建应用,如下图:
获取应用对应的AppKey和Umeng Message Secret,如下图:
appkey作为友盟对应用的唯一标识,在友盟推送和友盟统计,都是可以使用同一个的。
已经使用了友盟统计的用户,请从友盟后台已有应用中添加。
添加Channel ID
你可以用Channel ID来标识APP的推广渠道,作为推送消息时给用户分组的一个维度。设置方法如下:
在&application&标签下:
&meta-data
android:name="UMENG_CHANNEL"
android:value="Channel ID" &
&/meta-data&
将"android:value"中的"Channel ID"替换为APP的推广渠道。
或者,通过调用以下代码来设置推广渠道。
mPushAgent.setMessageChannel();
若同时在AndroidManifest.xml和代码设置了MessageChannel,则以代码设置的为准。
若在AndroidManifest.xml和代码里均没有设置,则使用Unknown作为Channel ID。
你可以使用20位以内的英文和数字为渠道定名(不要使用纯数字)。
友盟消息推送可以和友盟统计分析共用一个"Channel ID"字段。
setMessageChannel函数可以在调用注册接口后进行设置。
每台设备仅识别首次安装激活的渠道。
即使在统计分析sdk代码中设置了channel,也要在推送sdk代码中重新设置。两个sdk的channel是不公用的。
有关PushSDK中jar包和so包说明
jar包是com.umeng.message.libv_2.8.1.jar,so包支持多个平台,包括armeabi,armeabi-v7a,arm64-v8a,x86,x86_64,mips和mips64,每个目录下面包含libtnet-2.1.20.1-agoo.so包。
注意: 本SDK需要最新版本的 android-support-v4.jar 支持包。请在工程中添加 android-support-v4.jar 支持包。 关于v4 支持包说明, 请参考 。
开启推送服务
在应用的主Activity onCreate() 函数中开启推送服务
PushAgent mPushAgent = PushAgent.getInstance(context);
mPushAgent.enable();
可以通过接口 mPushAgent.disable(); 来关闭客户端的通知服务。
通过mPushAgent.isEnabled() 来查询状态。 状态表示有没有启用/关闭推送功能, 不表示推送后台服务的运行状态。
统计应用启动数据
在所有的Activity 的onCreate 方法或在应用的BaseActivity的onCreate方法中添加:
PushAgent.getInstance(context).onAppStart();
注意: 此方法与统计分析sdk中统计日活的方法无关!请务必调用此方法!
如果不调用此方法,不仅会导致按照"几天不活跃"条件来推送失效,还将导致广播发送不成功以及设备描述红色等问题发生。可以只在应用的主Activity中调用此方法,但是由于SDK的日志发送策略,有可能由于主activity的日志没有发送成功,而导致未统计到日活数据。
获取设备的device_token(可选)
可以在Debug模式下输出的logcat中看到device_token,也可以使用下面的方法来获取device_token。
String device_token = UmengRegistrar.getRegistrationId(context)
device_token为友盟生成的用于标识设备的id,长度为44位,不能定制和修改。同一台设备上每个应用对应的device_token不一样。
获取device_token的代码需要放在mPushAgent.enable();后面,注册成功以后调用才能获得device_token。
如果返回值为空,说明设备还没有注册成功, 需要等待几秒钟,同时请确保测试手机网络畅通。
如果一直都获取不到device_token,请参考:
在回调函数中获取测试设备的device_token可参考下文5.1部分进行获取。
添加代码完毕后,编译apk包。然后将apk包安装到联网的测试设备上并打开。
如果在编译和调试过程中遇到问题(例如混淆或无法编译),常见问题下编译问题的处理方法。
初次获取测试设备的Device Token。
//开启推送并设置注册的回调处理
mPushAgent.enable(new IUmengRegisterCallback() {
public void onRegistered(String registrationId) {
new Handler().post(new Runnable() {
public void run() {
//onRegistered方法的参数registrationId即是device_token
Log.d("device_token", registrationId);
mPushAgent.enable()和mPushAgent.enable(new IUmengRegisterCallback())调用一个即可。
Device Token为友盟生成的用于标识设备的id,长度为44位,不能定制和修改。同一台设备上每个应用对应的Device Token不一样。
如果返回值为空,说明SDK配置错误,或者网络异常,请进行相应的排查。
如果一直都获取不到Device Token,请参考:
如果不是初次获取Device Token,请参考4.2.3方法获取Device Token。
添加测试设备
在友盟消息推送服务后台(
)的“测试模式”中填写该设备的Device Token,将该设备添加为测试设备:
发送测试消息
在“测试模式”中发送测试消息。在测试设备上收到消息,表明SDK集成成功。
SDK 默认使用通知栏展示通知消息,开发者可以在友盟后台指定用户点击通知栏时的操作,包括“打开应用”、“打开指定页面(Activity)”、或“打开指定网页”。
如果没有收到消息,请参考中的处理方法。
测试模式具体介绍:
API对接(可选)
如果要使用API对接友盟服务器来发送消息,需要在友盟消息推送服务后台(
)填写服务器地址,进行白名单登记。
参考中的格式发送测试消息。需要填写正确的App Master Secret。
通知和消息
通知和消息的区别
在友盟后台,消息分为两类:
通知指在手机的通知栏(状态栏)上会显示的一条通知信息。一条通知,简单的填写纯文本的通知内容即可。通知主要用于提示用户的目的。应用加上通知功能,有利于提高应用的活跃度。
自定义消息不会被SDK展示到通知栏上。其内容完全由开发者自己定义。自定义消息主要用于应用的内部业务逻辑。一条自定义消息推送过来,有可能没有任何界面显示。
两者的主要区别是:通知发送后会在系统通知栏收到展现,同时响铃或振动提醒用户;
消息发送后不会在系统通知栏展现,SDK将消息传给第三方应用后需要开发者写展现代码才能看到。
通知是指发送后会在系统通知栏收到展现,同时响铃或振动提醒用户。该消息包含Notification所需的参数,如Notification的标题、内容、是否振动、点击后的相应动作等信息。
如下图所示:
其中,在友盟后台可以指定用户点击通知消息之后的动作,又可以分为以下五种:
使用系统默认浏览器打开指定网页
打开指定页面(Activity)
自定义行为
前3种打开动作默认由消息推送SDK负责处理,自定义行为则由开发者处理。
自定义通知打开动作
自定义通知打开动作,即自定义行为的数据放在custom字段。 在友盟后台或通过API发送消息时,在“后续动作”中的“自定义行为”中输入相应的值或代码即可实现。
在消息推送SDK里,有一个类UmengNotificationClickHandler,负责处理消息的点击事件。
该类主要有四个成员方法:
public void launchApp(Context context, UMessage msg);
public void openUrl(Context context, UMessage msg);
public void openActivity(Context context, UMessage msg);
public void dealWithCustomAction(Context context, UMessage msg);
这四个方法,分别对应于四种打开方式。其中,launchApp、openUrl、openActivity这三个方法已经由消息推送SDK完成,而dealWithCustomAction则只是一个空的方法。
若开发者需要处理自定义行为,则可以重写方法dealWithCustomAction();其中自定义行为的内容,存放在UMessage.custom中。下面是处理自定义行为的代码:
* 该Handler是在BroadcastReceiver中被调用,故
* 如果需启动Activity,需添加Intent.FLAG_ACTIVITY_NEW_TASK
UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler(){
public void dealWithCustomAction(Context context, UMessage msg) {
Toast.makeText(context, msg.custom, Toast.LENGTH_LONG).show();
mPushAgent.setNotificationClickHandler(notificationClickHandler);
以上代码需在Application的onCreate()中调用使用以下接口,而不是在Activity 中调用。如果在Activity中调用此接口,若应用进程关闭,则设置的接口会无效。请参考:
该Handler是在BroadcastReceiver中被调用。因此若需启动Activity,需为Intent添加Flag:Intent.FLAG_ACTIVITY_NEW_TASK,否则无法启动Activity。
若开发者想自己处理打开网页、打开APP、打开Activity,可重写相应的函数来实现。
自定义通知栏样式
在消息推送的SDK里,有一个类UmengMessageHandler,该类负责处理消息,包括通知消息和自定义消息。其中,有一个成员函数:getNotification,若SDK默认的消息展示样式不符合开发者的需求,可通过覆盖该方法来自定义通知栏展示样式。下面是demo里的示例代码:
public Notification getNotification(Context context,
UMessage msg) {
switch (msg.builder_id) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
RemoteViews myNotificationView = new RemoteViews(context.getPackageName(), R.layout.notification_view);
myNotificationView.setTextViewText(R.id.notification_title, msg.title);
myNotificationView.setTextViewText(R.id.notification_text, msg.text);
myNotificationView.setImageViewBitmap(R.id.notification_large_icon, getLargeIcon(context, msg));
myNotificationView.setImageViewResource(R.id.notification_small_icon, getSmallIconId(context, msg));
builder.setContent(myNotificationView)
.setSmallIcon(getSmallIconId(context, msg))
.setTicker(msg.ticker)
.setAutoCancel(true);
return builder.build();
//默认为0,若填写的builder_id并不存在,也使用默认。
return super.getNotification(context, msg);
具体介绍请参考文档
其中,msg.builder_id是服务器下发的消息字段,用来指定通知消息的样式。开发者可在Umeng Push网站上指定,默认值为0。
若要使用自定义通知栏样式,请勿重写方法dealWithNotificationMessage();否则,自定义通知栏样式将失效。
消息,即自定义消息,是指发送后不会在系统通知栏展现,SDK将消息传给第三方应用后需要开发者写展现代码才能看到的推送形式。 友盟消息推送SDK不对该消息进行展示和提醒,消息内容全部都传递给应用处理。其包含的内容
如下图所示:
自定义消息处理
消息推送SDK里,有一个类UmengMessageHandler,是负责消息的处理的。该类拥有两个成员函数,分别为:
public void dealWithNotificationMessage(Context context, UMessage msg);
public void dealWithCustomMessage(Context context, UMessage msg);
其中,dealWithNotificationMessage()方法负责处理通知消息,该方法已经由消息推送SDK 完成;dealWithCustomMessage()方法负责处理自定义消息,需由用户处理。
若开发者需要处理自定义消息,则需要将方法dealWithCustomMessage()重写,自定义消息的内容则存放在UMessage.custom里。
代码如下所示:
UmengMessageHandler messageHandler = new UmengMessageHandler(){
public void dealWithCustomMessage(final Context context, final UMessage msg) {
new Handler(getMainLooper()).post(new Runnable() {
public void run() {
// TODO Auto-generated method stub
// 对自定义消息的处理方式,点击或者忽略
boolean isClickOrDismissed =
if(isClickOrDismissed) {
//自定义消息的点击统计
UTrack.getInstance(getApplicationContext()).trackMsgClick(msg);
//自定义消息的忽略统计
UTrack.getInstance(getApplicationContext()).trackMsgDismissed(msg);
Toast.makeText(context, msg.custom, Toast.LENGTH_LONG).show();
mPushAgent.setMessageHandler(messageHandler);
以上代码需在 Application 的onCreate() 中调用,而不是在Activity 中调用。如果在Activity中调用此接口,若应用进程关闭, 则设置的接口会无效。 请参考:
若开发者想自己处理通知消息,可以重写方法dealWithNotificationMessage()。
 完全自定义处理
若开发者需要实现对消息的完全自定义处理,则可以继承 UmengBaseIntentService, 实现自己的Service来完全控制达到消息的处理。
实现一个类,继承 UmengBaseIntentService, 重写onMessage(Context context, Intent intent) 方法,并请调用super.onMessage(context, intent)。参考 demo 应用中MyPushIntentService。请参考下面代码:
public class MyPushIntentService extends UmengBaseIntentService{
private static final String TAG = MyPushIntentService.class.getName();
// 如果需要打开Activity,请调用Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);否则无法打开Activity。
protected void onMessage(Context context, Intent intent) {
// 需要调用父类的函数,否则无法统计到消息送达
super.onMessage(context, intent);
//可以通过MESSAGE_BODY取得消息体
String message = intent.getStringExtra(BaseConstants.MESSAGE_BODY);
UMessage msg = new UMessage(new JSONObject(message));
UTrack.getInstance(context).trackMsgClick(msg);
Log.d(TAG, "message="+message);
Log.d(TAG, "custom="+msg.custom);
//自定义消息的内容
Log.d(TAG, "title="+msg.title);
//通知标题
Log.d(TAG, "text="+msg.text);
//通知内容
to handle message here
// 完全自定义消息的处理方式,点击或者忽略
boolean isClickOrDismissed =
if(isClickOrDismissed) {
// 完全自定义消息的点击统计
UTrack.getInstance(getApplicationContext()).trackMsgClick(msg);
//完全自定义消息的忽略统计
UTrack.getInstance(getApplicationContext()).trackMsgDismissed(msg);
// 使用完全自定义消息来开启应用服务进程的示例代码
// 首先需要设置完全自定义消息处理方式
// mPushAgent.setPushIntentServiceClass(MyPushIntentService.class);
// code to handle to start/stop service for app process
JSONObject json = new JSONObject(msg.custom);
String topic = json.getString("topic");
if(topic != null && topic.equals("appName:startService")) {
// 在友盟portal上新建自定义消息,自定义消息文本如下
//{"topic":"appName:startService"}
if(Helper.isServiceRunning(context, NotificationService.class.getName()))
Intent intent1 = new Intent();
intent1.setClass(context, NotificationService.class);
context.startService(intent1);
} else if(topic != null && topic.equals("appName:stopService")) {
// 在友盟portal上新建自定义消息,自定义消息文本如下
//{"topic":"appName:stopService"}
if(!Helper.isServiceRunning(context, NotificationService.class.getName()))
Intent intent1 = new Intent();
intent1.setClass(context, NotificationService.class);
context.stopService(intent1);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
在AndroidManifest.xml 中声明。
&!-- 请填写实际的类名,下面仅是示例代码--&
&service android:name="【应用包名】.MyPushIntentService" android:process=":push"/&
在主Activity中调用。
mPushAgent.setPushIntentServiceClass(MyPushIntentService.class);
在onMessage()中,请务必调用super.onMessage(context, intent);否则,后台无法统计消息的到达。
打开消息行为的数据统计:默认情况下,SDK将用户点击通知栏的行为定义为“打开消息”。使用PushIntentService自定义处理后,SDK只能记录消息送达的数据,无法记录消息打开的数据。要记录消息打开的数据,你可以在应用中定义打开消息的语义,并使用以下接口向服务器发送消息打开的数据以便统计:UTrack.getInstance(context).trackMsgClick(msg);
也可以根据需要对自定义处理的消息进行忽略统计:UTrack.getInstance(context).trackMsgDismissed(msg);
如果需要打开Activity,需为Intent添加Flag:Intent.FLAG_ACTIVITY_NEW_TASK,否则无法启动Activity。
如果使用了完全自定义处理后,又想恢复成友盟的默认的处理,可以通过如下设置来恢复mPushAgent.setPushIntentServiceClass(null);;
消息推送实现自动更新
由于自动更新组件作出策略调整,若开发者想通过消息推送组件实现自动更新功能,建议采用推送应用下载链接的形式来实现。可将链接设置为官网的APK下载链接或第三方应用市场下载链接。此方法可确保开发者避开应用市场、系统厂商、运营商等多方对自动更新服务的限制,进而成功实现用消息推送实现自动更新功能。具体参考下图:
除已提供示例外,开发者可通过自定义更新通知消息的展示方式来实现不同的展示效果。
设置用户标签(tag)
您可以为用户加上标签,方便推送时按照标签来筛选。
mPushAgent.getTagManager().add("movie", "sport");
目前每个用户tag限制在1024个, 每个tag 最大256个字符。
下面的操作都是同步操作, 注意不要在主线程中调用。tag名称请不要加入URLEncode等变换处理,请使用原生字符串。
在原有标签基础上增加新标签。
public Result add(String... tags)
将之前添加的标签中的一个或多个删除。
public Result delete(String... tags)
删除之前添加的所有标签,重置为新标签。
public Result update(String... tags)
清除所有标签
删除之前添加的所有标签。
public void reset()
获取服务器端的所有标签
public List&String& list()
tag名称请不要使用URLEncode等变换处理,请使用原生字符串。 具体请参考
设置用户别名(alias)
如果你的应用有自有的用户id体系,可以在SDK中通过Alias字段上传自有用户id,按用户id向用户推送消息。
用户id可以是你的应用为每个用户自动生成的唯一id,也可以是用户采用第三方平台登录时从第三方平台获取到的用户id。要设置用户ID,可以使用以下接口:
mPushAgent.setAlias("", ALIAS_TYPE.SINA_WEIBO);
设置用户id和device_token的一一映射关系,确保同一个alias只对应一台设备:
mPushAgent.setExclusiveAlias("", ALIAS_TYPE.SINA_WEIBO);
若是要移除用户id,可调用以下接口:
mPushAgent.deleteAlias("", ALIAS_TYPE.SINA_WEIBO);
setAlias、setExclusiveAlias、deleteAlias是异步方法,可直接在主线程中调用。
若要使用新的alias,请先调用deleteAlias接口移除掉旧的alias,再调用addAlias添加新的alias,代码如下所示:
mPushAgent.deleteAlias("", ALIAS_TYPE.SINA_WEIBO);
mPushAgent.setAlias("", ALIAS_TYPE.SINA_WEIBO);
回传alias时需要指定该alias对应的类型(alias type),例如:自有id、新浪微博、腾讯微博、豆瓣等。
每个类型的alias同时只能存在一个,同一个类型的新alias会覆盖旧alias。
alias名称请不要使用URLEncode等变换处理,请使用原生字符串。
alias的绑定是需要获取到device_token为前提的,最好是在注册即enable的回调接口中进行alias的绑定,此时可以保证获取到device_token。
在2.7.0及以下版本的用户,可以使用addAlias、addExclusiveAlias、removeAlias方法,这些均是同步操作,请勿在主线程中调用。在2.8.1中,这些方法均已被废弃。
请参考alias的具体说明
自定义参数的使用
Push SDK 默认处理方式里,自定义参数均以字符串的形式进行传递。
开发者在发送通知和自定义消息时,可以添加自定义参数,友盟SDK会将自定义参数的内容传递给APP进行处理。
这些自定义参数将通过extra字段发送到客户端,下面是发送至客户端的JSON字符串。
"msg_id": "uu513912",
"display_type": "notification",
"alias": "",
"random_min": 0,
"title": "测试自定义参数",
"ticker": "测试自定义参数",
"text": "无",
"after_open": "go_app",
"url": "",
"activity": "",
"custom": "",
"play_vibrate": "true",
"play_sound": "true",
"play_lights": "true"
"extra": {
"key1": "value1",
"key2": "value2"
方法一:开发者可以通过SDK提供的回调方法来获取自定义参数。例如,重写UmengMessageHandler类中的getNotification(Context context, UMessage msg)方法,此方法会在通知展示到通知栏时回调。另外,也可重写UmengNotificationClickHandler类中的dealWithCustomAction(Context context, UMessage msg)方法,此方法会在通知被点击时回调。参数中的UMessage对象即为消息体,可在msg.extra获取到自定义参数.
for (Entry&String, String& entry : msg.extra.entrySet())
String key = entry.getKey();
String value = entry.getValue();
方法二:若开发使用Push SDK默认处理通知消息,则自定义参数将会通过Intent传递给相应的Activity。以下是SDK将参数放入Intent的代码:
private Intent addMessageToIntent(Intent intent, UMessage msg)
if (intent == null || msg == null || msg.extra == null)
for (Entry&String, String& entry : msg.extra.entrySet())
String key = entry.getKey();
String value = entry.getValue();
if (key!=null)
intent.putExtra(key, value);
开发者可以在相应的Activity中的onResume()方法内通过以下代码获得传递的参数:
Bundle bun = getIntent().getExtras();
if (bun != null)
Set&String& keySet = bun.keySet();
for (String key : keySet) {
String value = bun.getString(key);
同时需要将该Activity的launchMode设置为android:launchMode="singleTask",并重写onNewIntent方法:
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
通知免打扰模式
为免过度打扰用户,SDK默认在“23:00”到“7:00”之间收到通知消息时不响铃,不振动,不闪灯。如果需要改变默认的静音时间,可以使用以下接口:
public void setNoDisturbMode(int startHour, int startMinute, int endHour, int endMinute)
mPushAgent.setNoDisturbMode(23, 0, 7, 0);
可以通过下面的设置,来关闭免打扰模式:
mPushAgent.setNoDisturbMode(0, 0, 0, 0);
免打扰模式只需要设置一次即可生效,不需要在每次启动APP的时候都进行设置。
默认情况下,同一台设备在1分钟内收到同一个应用的多条通知时,不会重复提醒,同时在通知栏里新的通知会替换掉旧的通知。如需更改请参考:
通知栏按数量显示
通知栏可以设置最多显示通知的条数,当有新通知到达时,会把旧的通知隐藏。
public void setDisplayNotificationNumber(int number);
例如设置通知栏最多显示两条通知(当通知栏已经有两条通知,此时若第三条通知到达,则会把第一条通知隐藏):
mPushAgent.setDisplayNotificationNumber(2);
参数number可以设置为0~10之间任意整数。当参数为0时,表示不合并通知。
该方法可以多次调用,以最后一次调用时的设置为准。
自定义通知栏图标
如果在发送后台没有指定通知栏图标,SDK 将使用本地的默认图标,其中,大图标默认使用:drawable下的umeng_push_notification_default_large_icon,小图标默认使用drawable下的umeng_push_notification_default_small_icon,若开发者没有设置这两个图标,则默认使用应用的图标( &application
android:icon="@drawable/ic_launcher" )。 请确保应用设置了默认图标。
若开发者在发送后台指定了图片的链接,则该链接将通过Message的img字段进行传输。当SDK接受到消息后,会先下载图片,下载成功后显示通知;若下载失败,会自动重试两次(总共下载3次);若仍失败,则采用默认图片进行显示。
如果使用API方式(
)来发送消息, 可以指定icon 和largeIcon 字段,分别对应状态栏图标和通知栏下拉之后左侧大图标id ([R.drawable].icon), (请填写对应图片文件名,不包含扩展名) 请参考API文档。另外,MIUI暂时无法支持自定义通知栏图标,若开发者有需求,也可通过自定义通知栏样式来解决。具体介绍请参考文档:
小图标icon 要求为24dp*24dp 的图标, 或 24*24px在drawable-mdpi 下
大图标largeIcon 要求为 64*64 dp 的图标. 对应64*64px在drawable-mdpi 下, 128*128px 在drawable-xhdpi 中。
通常情况下, 只需要两个图标, 一个24*24px 的小图标(对于超高分辨率的机型的适配,可以适当提高小图标的尺寸,例如48px*48px),一个64*64px 的大图标, 都置于drawable-xhdpi 文件夹下。 制作图标时, 注意图片各边留一个像素的透明。 建议使用黑白图标。 具体参考
通知图标的显示有系统适配问题,有些手机系统,设置了通知的大图标,依然会使用应用图标;还有可能通知的Ticker图标显示不完全,只是部分显示。 关于通知的系统适配问题,需要开发者根据不同手机系统做相应的适配工作。
自定义通知栏声音
如果在发送后台没有指定通知栏的声音,SDK将采用本地默认的声音,即在res/raw/下的umeng_push_notification_default_sound。若无此文件,则默认使用系统的Notification声音。
若需要在线配置声音,则需先将与配置的声音文件放置在res/raw下,然后自发送后台指定声音的id,即R.raw.[sound]里的sound
自定义前台通知显示
如果应用在前台的时候,开发者可以自定义配置是否显示通知,默认情况下,应用在前台是显示通知的。
开发者更改前台通知显示设置后,会根据更改生效。
若要不显示前台通知,调用接口如下:
mPushAgent.setNotificaitonOnForeground(false);
注意:此方法请在PushAgent.enable方法之前调用。
自定义资源包名
当使用android studio开发环境时,是基于gradle的配置方式,资源文件的包和应用程序的包是可以分开的,为了正确的找到资源包名,为开发者提供了自定义的设置资源包的接口。
当资源包名和应用程序包名不一致时,调用设置资源包名的接口:
mPushAgent.setResourcePackageName(String packageName);
自定义是否检查集成配置文件
为了便于开发者更好的集成配置文件,我们提供了对于AndroidManifest配置文件的检查工具,可以自行检查开发者的配置问题。SDK默认是不检查集成配置文件的,在线上版本请关掉该配置检查,或者去掉这行检查代码(sdk默认是不做该项检查的)。
自定义检查集成配置文件的接口如下:
mPushAgent.setPushCheck(boolean pushCheck);
Push注册回调和注销回调
在V1.3.0上增加了两个回调:
注册回调:IUmengRegisterCallback;当开启友盟推送时,可传入注册回调,即PushAgent.enable(IUmengRegisterCallback)。
注销回调:IUmengUnregisterCallback;当关闭友盟推送时,可传入注销回调,即PushAgent.disable(IUmengUnregisterCallback)。
回调的代码并不是在主线程中进行调用,故若需要调用到主线程,需在handler进行操作。代码如下:
public IUmengRegisterCallback mRegisterCallback = new IUmengRegisterCallback() {
public void onRegistered(String registrationId) {
handler.post(new Runnable() {
public void run() {
updateStatus();
增加本地通知功能,开发者可以使用SDK提供的对于本地通知的增删查改功能。
本地通知的接口如下:
mPushAgent.addLocalNotification(UmengLocalNotification localNotification);
//增加本地通知
mPushAgent.updateLocalNotification(UmengLocalNotification localNotification);
//修改本地通知
mPushAgent.deleteLocalNotification(String localNotificationId);
//删除本地通知
mPushAgent.clearLocalNotifications();
//清除本地通知
mPushAgent.findLocalNotification(String localNotificationId);
//根据Id查找本地通知
mPushAgent.findLocalNotifications(String text);
//根据包含的title或者content查找本地通知
mPushAgent.findAllLocalNotifications();
//查找所有本地通知
mPushAgent.setLocalNotificationIntervalLimit(boolean limit);
//设置时间间隔限制,默认是限制的,最少间隔是10分钟
 自定义本地通知
开发者可以自定义本地通知
UmengLocalNotification localNotification = new UmengLocalNotification();
自定义本地通知相关属性:
localNotification.setTitle(String title);
//设置通知标题
localNotification.setContent(String content);
//设置通知内容
localNotification.setTicker(String ticker);
//设置通知提示
localNotification.setDateTime(String dateTime);
//设置通知开始时间
localNotification.setLunarDateTime(String dateTime);
//设置通知开始的阴历时间
localNotification.setSpecialDay(int specialDay);
//设置通知节日
localNotification.setRepeatingNum(int repeatingNum);
//设置通知重复数,默认是1
localNotification.setRepeatingInterval(int repeatingInterval);
//设置通知重复间隔,默认是1
localNotification.setRepeatingUnit(int repeatingUnit);
//设置通知重复单位
开发者可以自定义本地通知样式
UmengNotificationBuilder notificationBuilder = localNotification.getNotificationBuilder();
针对通知通用属性的设置:
notificationBuilder.setDefaults(int defaults);
//设置Defaults
notificationBuilder.setFlags(int flags);
//设置Flags
notificationBuilder.setSmallIconDrawable(String drawable);
//设置小图标
notificationBuilder.setLargeIconDrawable(String drawable);
//设置大图标
notificationBuilder.setSoundDrawable(String drawable);
//设置声音
notificationBuilder.setPlayVibrate(boolean vibrate);
//设置振动
notificationBuilder.setPlayLights(boolean lights);
//设置呼吸灯
notificationBuilder.setPlaySound(boolean sound);
//设置声响
notificationBuilder.setScreenOn(boolean screenOn);
//设置屏显
针对通知自定义样式的设置:
notificationBuilder.setLayoutId(int layoutId);
//设置自定义样式Id
notificationBuilder.setLayoutTitleId(int layoutTitleId);
//设置自定义标题Id
notificationBuilder.setLayoutContentId(int layoutContentId);
//设置自定义内容Id
notificationBuilder.setLayoutIconId(int layoutIconId);
//设置自定义小图标Id
notificationBuilder.setLayoutIconDrawableId(int layoutIconDrawableId);
//设置自定义大图标Id
//注意:自定义样式的5个参数都必须设置,否则通知自定义样式会无法展示。
为本地通知设置自定义通知样式
localNotification.setNotificationBuilder(notificationBuilder);
dateTime定义的日期格式为yyyy-MM-dd HH:mm:ss
specialDay是指通知是否在某个节日,默认是不在节日通知。目前是支持以下几种节日:
UmengLocalNotification.NEW_YEAR_DAY //元旦
UmengLocalNotification.CHINESE_NEW_YEAR_EVE //除夕
UmengLocalNotification.CHINESE_NEW_YEAR //春节
UmengLocalNotification.LANTERN //元宵节
UmengLocalNotification.QINGMING_FESTIVAL //清明节
UmengLocalNotification.LABOR_DAY //劳动节
UmengLocalNotification.DRAGON_BOAT_FESTIVAL //端午节
UmengLocalNotification.QIXI_FESTIVAL //七夕节
UmengLocalNotification.MID_AUTUMN_FESTIVAL //中秋节
UmengLocalNotification.NATIONAL_DAY //中秋节
UmengLocalNotification.CHUNG_YEUNG_FESTIVAL //重阳节
UmengLocalNotification.LABA_FESTIVAL //腊八节
repeatingUnit,通知重复的单位,默认是天,包括如下:
UmengLocalNotification.REPEATING_UNIT_YEAR
UmengLocalNotification.REPEATING_UNIT_MONTH
UmengLocalNotification.REPEATING_UNIT_DAY
UmengLocalNotification.REPEATING_UNIT_HOUR
UmengLocalNotification.REPEATING_UNIT_MINUTE
UmengLocalNotification.REPEATING_UNIT_SECOND
避免点击通知栏之后重复打开已经打开过的Activity
在通过通知栏打开的Activity加上singleTask 属性。
支持多包名
该功能仅在Push SDK V1.4.0及以后版本中支持。
若一个APP针对不同渠道有不同的包名,则可通过开通多包名支持一个AppKey对应多个包名发送消息。如下图所示:
如果同一设备安装同一应用的不同包名的多个安装包,只有最后安装的应用可以正常收到推送消息。
主包名指的是默认的包名或者大部分渠道用到的包名,开发者自行决定哪个是主包名即可。另外,如果之前已经填写过包名,那么申请开通多包名之后,之前已经填写过的包名就会默认成为主包名。
修改包名后,注意AndroidManifest.xml文件中相应的地方也需要进行包名替换,详见3.2
多包名的具体用法,请参考
客户端控制消息到达响铃、震动、呼吸灯
有三种状态: MsgConstant.NOTIFICATIONPLAYSERVER(服务端控制)、MsgConstant.NOTIFICATIONPLAYSDKENABLE(客户端允许)、MsgConstant.NOTIFICATIONPLAYSDKDISABLE(客户端禁止)* 服务端控制:通过服务端推送状态来设置客户端响铃、震动、呼吸灯的状态 * 客户端允许:不关心服务端推送状态,客户端都会响铃、震动、呼吸灯亮 * 客户端禁止:不关心服务端推送状态,客户端不会响铃、震动、呼吸灯亮
通过以下方法可以设置:
mPushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SERVER); //声音
mPushAgent.setNotificationPlayLights(MsgConstant.NOTIFICATION_PLAY_SERVER);//呼吸灯
mPushAgent.setNotificationPlayVibrate(MsgConstant.NOTIFICATION_PLAY_SERVER);//振动
实时地理位置推送(Beta)
实时地理位置推送:实现对用户划定区域内实时人群推送消息。
注意:此功能仅适用于Android 2.8.1L_Beta版本sdk。只有在集成Android 2.8.1L_Beta版本sdk后,U-Push后台才会展示实时地理位置推送功能。
进入区域:消息有效期内,对进入热点区域的用户推送消息;
离开区域:消息有效期内,对离开热点区域的用户推送消息;
附近区域:消息有效期内,对 进入 热点区域周边(不含热点区域)xx米内用户推送消息。
设置实时地理位置推送发送频率,可选范围为2秒/次 ~ 30分钟/次。若不调用该方法,则默认10分钟发送一次地理位置信息:
mPushAgent.setLocationInterval(int seconds);
开启实时地理位置推送,覆盖在指定地理区域内的用户:
mPushAgent.startLBS();
停止实时地理位置推送,调用该方法后,SDK不再发送地理位置信息:
mPushAgent.stopLBS();
PushAgent的接入类;
public class
extends Object
java.lang.Object
? com.umeng.message.PushAgent
//参考集成文档的4.2.1
void enable()
//开启推送
void enable(IUmengRegisterCallback callback)
//开启推送并设置注册回调
void disable()
//关闭推送
void disable(IUmengUnregisterCallback callback)
//关闭推送并设置注销回调
//参考集成文档的4.2.2
void onAppStart()
//统计应用启动
//参考集成文档的6.3.3
void setPushIntentServiceClass(Class clz)
//设置完全自定义处理类
//参考集成文档7.5
void setNoDisturbMode(int startHour, int startMinute, int endHour, int endMinute)
//设置通知免打扰模式
//参考集成文档7.3
boolean addAlias(String alias, String type) throws HttpRequestException, JSONException, Exception
//设置用户id
boolean addExclusiveAlias(String alias, String type) throws HttpRequestException, JSONException, Exception
//设置用户唯一id
boolean removeAlias(String alias, String type) throws HttpRequestException, JSONException, Exception
//删除用户id
//参考集成文档7.8
void setNotificaitonOnForeground(boolean foreground)
//自定义前台通知显示
//参考集成文档7.9
void setResourcePackageName(String packageName)
//自定义资源包名
//参考集成文档7.10
void setPushCheck(boolean pushCheck)
//自定义是否检查集成配置文件
void setMergeNotificaiton(boolean merge)
//自定义是否覆盖通知栏通知
void setMuteDurationSeconds(int seconds)
//自定义通知的静默时间
void setMessageHandler(UHandler handler)
//自定义消息处理类
void setNotificationClickHandler(UHandler handler)
//自定义通知处理类
UmengMessageHandler消息接收处理类;
public class
extends Object
java.lang.Object
implements UHandler
? com.umeng.message.UmengMessageHandler
void dealWithNotificationMessage(Context context, UMessage msg)
//处理通知
//参考集成文档6.2.3
Notification getNotification(Context context, UMessage msg)
//自定义通知栏样式
//参考集成文档6.3.2
void dealWithCustomMessage(Context context, UMessage msg)
//处理自定义消息
UmengNotificationClickHandler通知处理类;
public class
extends Object
java.lang.Object
implements UHandler
? com.umeng.message.UmengNotificationClickHandler
//参考集成文档6.2.2
void launchApp(Context context, UMessage msg)
//点击通知打开应用
void openUrl(Context context, UMessage msg)
//点击通知打开网页
void openActivity(Context context, UMessage msg)
//点击通知打开应用内的指定页面
void dealWithCustomAction(Context context, UMessage msg)
//点击通知的自定义行为处理
IUmengRegisterCallback注册回调接口;
public interface
extends Object
java.lang.Object
? com.umeng.message.IUmengRegisterCallback
//参考集成文档7.1.1
void onRegistered(String registrationId)
//注册回调
  IUmengUnregisterCallback注销回调接口;
public interface
extends Object
java.lang.Object
? com.umeng.message.IUmengUnregisterCallback
//参考集成文档7.11
void onUnregistered(String registrationId)
//注销回调
 TagManager标签管理类;
public class
extends Object
java.lang.Object
? com.umeng.message.tag.TagManager
//参考集成文档7.2
public Result add(String... tags)
//添加标签
Result delete(String... tags)
//删除标签
void reset()
//清除所有标签
List list()
//获取服务器端的所有标签
void update(String... tags)
//更新标签(清除以前所有标签更新为最新的标签)
收不到消息
详见下文:
如何统计Message的到达、点击和忽略?
开发者仅需要自己统计自定义消息的点击和忽略;其他的统计,均已由消息推送SDK完成。开发者可以通过调用以下两个方法来完成统计:
UTrack.getInstance(context).trackMsgClick(msg, false);//统计消息被点击或者处理
UTrack.getInstance(context).trackMsgDismissed(msg, false);//统计消息被忽略
如何将UMessage放入Intent中传递?
通过调用UMessage.getRaw().toString(),可获取到UMessage的原始JSON字符串,再将其放入到Intent中。代码如下所示:
intent.putExtra("EXTRA_KEY_MSG", msg.getRaw().toString());
在测试时可以设置调试模式
正式发布应用时,请务必将本开关关闭,避免影响用户正常使用APP。
mPushAgent.setDebugMode(boolean debug)
打开调试模式后,可以在logcat里面看到比较详细的log信息,以方便调试和定位问题。
如果APP进行了混淆,请添加:
-dontwarn com.ut.mini.**
-dontwarn okio.**
-dontwarn com.xiaomi.**
-dontwarn com.squareup.wire.**
-dontwarn android.support.v4.**
-keepattributes *Annotation*
-keep class android.support.v4.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class okio.** {*;}
-keep class com.squareup.wire.** {*;}
-keep class com.umeng.message.protobuffer.* {
public &fields&;
public &methods&;
-keep class com.umeng.message.* {
public &fields&;
public &methods&;
-keep class org.android.agoo.impl.* {
public &fields&;
public &methods&;
-keep class org.android.agoo.service.* {*;}
-keep class org.android.spdy.**{*;}
-keep public class **.R$*{
public static final int *;
//如果compileSdkVersion为23,请添加以下混淆代码
-dontwarn org.apache.http.**
-dontwarn android.webkit.**
-keep class org.apache.http.** { *; }
-keep class mons.codec.** { *; }
-keep class mons.logging.** { *; }
-keep class patibility.** { *; }
-keep class android.net.http.** { *; }
如果在编译或者混淆的过程中遇到类似下面的错误,
Proguard returned with error code 1. See console
Note: there were 371 duplicate class definitions.
Warning: org.android.agoo.client.ElectionHelper: can't find referenced field 'long firstInstallTime' in library class android.content.pm.PackageInfo
Warning: org.android.agoo.client.MessageService: can't find referenced field 'java.util.concurrent.TimeUnit MINUTES' in library class java.util.concurrent.TimeUnit
Warning: there were 2 unresolved references to library class members.
You probably need to update the library versions.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)
java.io.IOException: Please correct the above warnings first.
at proguard.Initializer.execute(Initializer.java:369)
at proguard.ProGuard.initialize(ProGuard.java:212)
at proguard.ProGuard.execute(ProGuard.java:87)
at proguard.ProGuard.main(ProGuard.java:484)
请将Android 工程对Android SDK的引用 设为最新版本(Eclipse-& 工程右键-& 属性-& Android-& Android4.3 或最新版SDK)。 minSdkVersion可以设为8.
消息推送SDK 不支持在QEMU模拟器上调试,调试时请尽量使用真机。
调试时 mPushAgent.isEnabled()
状态表示有没有启用推送功能,不表示推送后台服务在不在运行。
调试时确认推送服务运行状态的方法
打开调试模式后, 启动应用,在DDMS 中可以看到:Push Service 结尾的进程,这是友盟推送服务使用的后台进程。由于友盟推送SDK 使用了共享通道的技术,此进程可能在其他应用的包名下运行。 同时在Logcat 中可以看到类似 connect[7170]---&[onHeart()] 的log, 表明应用和友盟的推送通道成功建立。
11-21 14:32:15.767: D/AgooService(24977): receiver---&[android.intent.action.SCREEN_ON]---&[try connect]
11-21 14:32:16.838: D/MessagePush(24977): tryConnect----&[force:false][started:true]
11-21 14:32:20.202: D/MessagePush(24977): connect[7170]---&[onHeart()]
查看设备的Device Token的方法
可以在Debug模式下输出的logcat中看到Device Token,也可以使用下面的方法来获取Device Token。
String device_token = UmengRegistrar.getRegistrationId(context)
Device Token为友盟生成的用于标识设备的id,长度为44位,不能定制和修改。同一台设备上每个应用对应的Device Token不一样。
获取Device Token的代码需要放在mPushAgent.enable();后面,注册成功以后调用才能获得Device Token。
如果返回值为空, 说明设备还没有注册成功, 需要等待几秒钟,同时请确保测试手机网络畅通。
如果在Logcat 中发现服务器的消息到达客户端, 但是SDK 无法展示通知栏, 请检查应用是否在 AndroidManifest.xml 中为 &Application& 设置了android:icon 属性。
消息送达时间
在测试阶段,广播或者发送给部分人的消息会在发送后的10分钟之内送达。发送给单个Device Token的消息会在1分钟内送达。
如果发现消息很长时间才到,有可能是因为网络状况不好,导致设备离线,到设备再次上线时才收到消息。
消息提醒的一分钟冷却时间
同一台设备在某段时间内(默认是60秒)收到多条消息时,不会重复提醒,可以通过下面的函数来设置冷却时间。
PushAgent.getInstance(context).setMuteDurationSeconds(int seconds)
通知栏如何展示多条通知
默认情况下,使用SDK提供的通知类型,当设备收到多条通知时,通知栏只展示最新的一条通知。可以使用下面的方法来控制通知栏最多显示通知的条数,当有新通知到达时,会把旧的通知隐藏。
public void setDisplayNotificationNumber(int number);
注意:v2.7.0及以下版本的用户可以调用mPushAgent.setMergeNotificaiton(false);来展示多条通知。请慎用此开关,以免用户看到多条通知时,产生不好的用户体验。
消息过期时间
发送一条消息后,有些设备当时没有联网,无法收到该条消息。待设备联网时,如果消息没有过期,则设备可以收到该条消息;如果消息已经过期,则设备不会收到该条消息。
发送消息时,过期时间应设定为晚于发送时间1小时以上。如果过期时间与发送时间间隔太短,可能任务处理时就已经过期,导致消息发送失败。
用户打开消息的统计数据不是立即回传的,会有5-10分钟的延时,因此测试时在后台看到的统计数据也会有相应的延时。如果数据还未回传时,应用被Android系统停止,可能造成统计数据不回传,待下次启动时才会回传。
选择发送给部分人时,筛选条件中没有显示我要的数据
筛选条件的数据是在应用注册以后发送回来的。收到数据到数据在页面上显示出来大约需要10分钟,稍等几分钟就能在前端看到和选择了。
消息发送时的新增设备
一条消息被服务器开始处理以后,要发送的设备就已经确定了,在这期间的新增设备不会收到这条消息。
通知图标的适配问题
通知图标在不同手机系统上有适配性问题,比如小米或者魅族的某些手机上,设置大图标不起作用,仍然显示应用图标,再比如,三星某些手机上,通知的Ticker所显示的图标不完全,只显示部分图标等。
这些问题属于系统适配问题,需要开发者结合不同手机系统做相应的适配工作。
集成友盟推送获取不到device_token
后台显示消息发送成功,设备并没有收到消息
Logcat有消息 通知栏收不到
小白集成友盟推送Android 2.6.0(图文并茂)
播的类型的介绍及注意事项
消息推送的送达率和哪些因素有关? 
Android的device-token什么情况下会变化?
更多常见问题请点击访问:
混淆配置检查
在对应用打Release包的时候,如果编译不通过并出现can't find referenced class等类似无法找到类的警告时,请对照文档9.3检查应用的混淆配置,文档中的混淆配置需要完整的复制到应用中。
对于应用程序是否注册成功,可以通过抓包软件进行抓包,查看下的register的Response值,如果注册成功,则会显示success。
对于应用是否获取到device_token,2.7.0及以上版本用户可以通过查看下的Request值(2.6.0及以下用户请查看下的Request值),如果成功获取到device_token(device Id),则会显示如下内容:
umeng:50e26cdf0000031
android@umeng
Aq1z-o6vH1lTbENGWdkb5xKQ_Ic7mRK1m5xB2v0YKWUy
app_version_code
agoo_version_code
如果本文档未能解决您的问题,请您将问题发邮件至或者联系客服:(在线时间:工作日10:00~18:00),以及消息推送官方QQ群:(加群需提供友盟appkey审核)。我们会尽快回复您。
如果可以附上相关日志,我们可以更好的帮助您解决问题,通过mPushAgent.setDebugMode(boolean debug)打开Debug模式,在logcat里查看log,发布应用时请去掉。

我要回帖

更多关于 git push f u 的文章

 

随机推荐