极光消息推送:
极光推送(JPush)是一个端到端的推送服务,使得服务器端消息能够及时地推送到终端用户手机上,让开发者积极地保持与用户的连接
主要功能
- 保持与服务器的长连接,以便消息能够即时推送到达客户端
- 接收通知与自定义消息,并向开发者App 传递相关信息
主要特点
- 客户端维持连接占用资源少、耗电低
- SDK丰富的接口,可定制通知栏提示样式
- 服务器大容量、稳定
接入步骤
1.打开极光官网进行注册
2.登录极光官网进入用户的后台管理进行创建应用(按照步骤一步一步来)
3.应用创建成功后,可以拿到AppKey(后期用于在Android清单文件中配置)
4.下载极光推送Android SDK
5.下载成功后将Jpush-android-3.x.x-release.zip压缩包的内容解压如下图所示目录结构
example 是官方的demo案例
libs是JPush的Jar包和so文件
AndroidManifest.xml JPush清单文件配置
1.将libs目录下的所有jar包复制到Android Studio中的Project目录结构下的libs目录
2.将libs目录下的所有so文件复制到Android Studio中的jniLibs目录下。如下图所示
6.配置AndroidManifest.xml清单文件
根据 SDK 压缩包里的 AndroidManifest.xml样例文件,来配置应用程序项目的AndroidManifest.xml 。
主要步骤为:
- 复制备注为 “Required” 的部分
- 将标注为“您应用的包名”的部分,替换为当前应用程序的包名
- 将标注为“您应用的Appkey”的部分,替换为在JPush官网上注册该应用的的AppKey,例如:9fed5bcb7b9b87413678c407
清单文件示例
在你应用的Application中的onCrate()方法中进行初始化例如:
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
JPushInterface.setDebugMode(true);
JPushInterface.init(this);
}
}
测试确认
- 确认所需的权限都已经添加。如果必须的权限未添加,日志会提示错误。
- 确认 AppKey(在Portal上生成的)已经正确的写入 Androidmanifest.xml 。
- 确认在程序启动时候调用了init(context) 接口
- 确认测试手机(或者模拟器)已成功连入网络 + 客户端调用 init 后不久,如果一切正常,应有登录成功的日志信息
- 启动应用程序,在 Portal 上向应用程序发送自定义消息或者通知栏提示。详情请参考管理Portal。
在几秒内,客户端应可收到下发的通知或者正定义消息,如果 SDK 工作正常,则日志信息会如下:
[JPushInterface] action:init…….
[PushService] Login succeed!
如图所示,客户端启动分为 4 步:
- 检查 metadata 的 appKey 和 channel ,如果不存在,则启动失败
- 初始化 JPush SDK,检查 JNI 等库文件的有效性,如果库文件无效,则启动失败
- 检查 Androidmanifest.xml,如果有 Required 的权限不存在,则启动失败
- 连接服务器登录,如果存在网络问题,则登陆失败,或者前面三步有问题,不会启动JPush SDK
测试JPush消息推送
进入你的极光推送后台管理选择刚才创建的应用进行推送。推送的类型如下图所示
可以自行到后台管理查看配置
这时候如果前面的配置都没有问题的话,在后台推送消息后,前台是可以正确收到的。
别名与标签使用
为什么需要别名与标签?
推送消息时,要指定推送的对象:全部,某一个人,或者某一群人。
全部很好办,针对某应用“群发”就好了。Portal与API都支持向指定的 appKey 群发消息。
要指定向某一个特定的人,或者某一群特定的人,则相对复杂。因为对于 JPush 来说,某一个人就是一个注册ID,这个注册ID与开发者App没有任何关系,或者说对开发者App是没有意义的。
如果要对开发者App有意义的某个特定的用户推送消息,则需要:把 JPush 注册用户与开发者App 用户绑定起来。
这个绑定有两个基本思路:
- 把绑定关系保存到 JPush 服务器端
- 把绑定关系保存到开发者应用服务器中
前者,就是这里要说到的:别名与标签的功能。这个机制简单易用,适用于大多数开发者。
后者,则是 JPush 提供的另外一套 RegistrationID 机制。这套机制开发者需要有应用服务器来维护绑定关系,不适用于普通开发者。Android SDK 1.6.0 版本开始支持。
使用方式
别名与标签的机制,其工作方式是:
客户端开发者App调用 setAlias或者setTags API 来设置关系
JPush SDK 把该关系设置保存到 JPush Server 上
在服务器端推送消息时,指定向之前设置过的别名或者标签推送
使用标签
用于给某一群人推送消息。
标签类似于博客里为文章打上 tag ,即为某资源分类。
动态标签
JPush 提供的设置标签的 API 是在客户端的。开发者如何做到在自己的服务器端动态去设置分组呢? 比如一个企业OA系统,经常需要去变更部门人员分组。以下是大概的思路:
设计一种自定义消息格式(业务协议),App解析后可以调用 JPush SDK setAliasAndTags API 来重新设置标签(分组)
例:
{"action":"resetTags", "newTags":["dep_level_1":"A公司", "dep_level_2":"技术部", "dep_level_3":"Android开发组", "address":"深圳", "lang":"zh"]}
要动态设置分组时,推送这条自定义消息给指定的用户
使用别名的机制,推送到指定的用户。
客户端App 调用 JPush SDK API 来设置新的标签
别名与标签设置异常处理
由于网络连接不稳定的原因,有一定的概率 JPush SDK 设置别名与标签会失败。 App 开发者合理地处理设置失败,则偶尔失败对应用的正常使用 JPush 影响是有限的。
自定义通知栏样式教程
通知 vs 自定义消息
极光推送包含有通知与自定义消息两种类型的推送。本文描述他们的区别,以及建议的应用场景。
两者的区别 - 功能角度
通知
通知(Notification),指在手机的通知栏(状态栏)上会显示的一条通知信息。这是 Android / iOS 的基本功能。通知主要用于提示用户。一条通知,简单的填写纯文本的通知内容即可。应用加上通知功能,有利于提高应用的活跃度。
自定义消息
自定义消息不是通知,默认不会被SDK展示到通知栏上,极光推送仅负责透传给SDK。其内容和展示形式完全由开发者自己定义。自定义消息主要用于应用的内部业务逻辑和特殊展示需求。
两者的区别 - 开发者使用角度
通知
简单场景下的通知,用户可以不写一行代码,而完全由SDK来负责默认的效果展示,以及默认用户点击时打开应用的主界面。JPush Android SDK 提供了 API让开发者来定制通知栏的效果,请参考:自定义通知栏样式教程;也提供了 接收推送消息Receiver 让你来定制在收到通知时与用户点击通知时的不同行为。
自定义消息
SDK 不会把自定义消息展示到通知栏。所以调试时,需要到日志里才可以看到服务器端推送的自定义消息。自定义消息一定要由开发者写 接收推送消息Receiver 来处理收到的消息。
注意:
当自定义消息内容msg_content为空时,SDK不会对消息进行广播,使得app无法接收到推送的消息,因此建议在使用自定义消息推送时添加内容。
使用通知
请参考以下示例代码。
public class MyReceiver extends BroadcastReceiver {
private static final String TAG = "MyReceiver";
private NotificationManager nm;
@Override
public void onReceive(Context context, Intent intent) {
if (null == nm) {
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
Bundle bundle = intent.getExtras();
Logger.d(TAG, "onReceive - " + intent.getAction() + ", extras: " + AndroidUtil.printBundle(bundle));
if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
Logger.d(TAG, "JPush用户注册成功");
} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
Logger.d(TAG, "接受到推送下来的自定义消息");
} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
Logger.d(