Android SDK 集成指南

使用提示

本文是 JPush Android SDK 标准的集成指南文档。用以指导 SDK 的使用方法,默认读者已经熟悉 IDE(Eclipse 或者 Android Studio)的基本使用方法,以及具有一定的 Android 编程知识基础。

本篇指南匹配的 JPush Android SDK 版本为:3.0.0 及以后版本。

  • 3 分钟快速 Demo(Android):如果您想要快速地测试、感受下极光推送的效果,请参考本文在几分钟内跑通 Demo。
  • 极光推送文档网站上,有极光推送相关的所有指南、API、教程等全部的文档。包括本文档的更新版本,都会及时地发布到该网站上。
  • 如果您看到本文档,但还未下载 Android SDK,请访问 SDK 下载页面下载。

产品功能说明

极光推送(JPush)是一个端到端的推送服务,使得服务器端消息能够及时地推送到终端用户手机上,让开发者积极地保持与用户的连接,从而提高用户活跃度、提高应用的留存率。极光推送客户端支持 Android,iOS 两个平台。

本 Android SDK 方便开发者基于 JPush 来快捷地为 Android App 增加推送功能。

主要功能

  • 保持与服务器的长连接,以便消息能够即时推送到达客户端
  • 接收通知与自定义消息,并向开发者 App 传递相关信息

主要特点

  • 客户端维持连接占用资源少、耗电低
  • SDK 丰富的接口,可定制通知栏提示样式
  • 服务器大容量、稳定

jpush-android-3.x.x-release.zip 集成压缩包内容

  • AndroidManifest.xml
    • 客户端嵌入 SDK 参考的配置文件
  • libs/jcore-android.1.x.x.jar
    • 极光开发者服务的核心包。
  • libs/jpush-android-3.x.y.jar
    • JPush SDK 开发包。
  • libs/(cpu-type)/libjcore1xx.so
    • 各种 CPU 类型的 native 开发包。
  • res
    • 集成 SDK 必须添加的资源文件
  • example
    • 是一个完整的 Android 项目,通过这个演示了 JPush SDK 的基本用法,可以用来做参考。

SDK 所支持的 Android 系统版本

目前 SDK 只支持 Android 2.3 或以上版本的手机系统。

富媒体信息流功能则需 Android 3.0 或以上版本的系统。

jcenter 自动集成步骤

说明 : 使用 jcenter 自动集成的开发者,不需要在项目中添加 jar 和 so,jcenter 会自动完成依赖;在 AndroidManifest.xml 中不需要添加任何 JPush SDK 相关的配置,jcenter 会自动导入。

注意 :如果需要处理收到的消息、使用 3.0.7 版本支持的别名与标签的新接口,AndroidManifest 中的自定义广播接收器仍需开发者手动配置,参考 SDK 压缩包里的 AndroidManifest.xml 样例文件。
  • 如果开发者需要修改组件属性,可以在本地的 AndroidManifest 中定义同名的组件并配置想要的属性,然后用 xmlns:tools 来控制本地组件覆盖 jcenter 上的组件。示例:
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2. package="com.android.tests.flavorlib.app"
  3. xmlns:tools="http://schemas.android.com/tools">
  4. <application
  5. android:icon="@drawable/icon"
  6. android:name="com.example.jpushdemo.ExampleApplication"
  7. android:label="@string/app_name" >
  8. <service android:name="cn.jpush.android.service.PushService"
  9. android:process=":multiprocess"
  10. tools:node="replace" >
  11. ……
  12. </service>
  13. ……
  14. </application>
  15. ……
  16. </manifest>
  • 确认 android studio 的 Project 根目录的主 gradle 中配置了 jcenter 支持。(新建 project 默认配置就支持)
  1. buildscript {
  2. repositories {
  3. jcenter()
  4. }
  5. ......
  6. }
  7. allprojets {
  8. repositories {
  9. jcenter()
  10. }
  11. }
  • 在 module 的 gradle 中添加依赖和 AndroidManifest 的替换变量。
  1. android {
  2. ......
  3. defaultConfig {
  4. applicationId "com.xxx.xxx" //JPush 上注册的包名.
  5. ......
  6. ndk {
  7. //选择要添加的对应 cpu 类型的 .so 库。
  8. abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'
  9. // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
  10. }
  11. manifestPlaceholders = [
  12. JPUSH_PKGNAME : applicationId,
  13. JPUSH_APPKEY : "你的 Appkey ", //JPush 上注册的包名对应的 Appkey.
  14. JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
  15. ]
  16. ......
  17. }
  18. ......
  19. }
  20. dependencies {
  21. ......
  22. compile 'cn.jiguang.sdk:jpush:3.2.0' // 此处以JPush 3.2.0 版本为例。
  23. compile 'cn.jiguang.sdk:jcore:1.2.7' // 此处以JCore 1.2.7 版本为例。
  24. ......
  25. }

: 如果在添加以上 abiFilter 配置之后 android Studio 出现以下提示:

  1. NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin

则在 Project 根目录的 gradle.properties 文件中添加:

  1. android.useDeprecatedNdk=true

: 使用 NDK r17 时,可能 Android Studio 会出现以下提示:

  1. A problem occurred starting process command
  2. ‘/Users/xxx/Library/Android/sdk/ndk-bundle/toolchains/mips64el-linux-android-4.9/prebuilt
  3. /darwin-x86_64/bin/mips64el-linux-android-strip
  4. 系统找不到指定的文件

这是因为 NDK r17 之后不再支持 mips 平台,在 build.gradle 里增加如下配置可解决

  1. android {
  2. defaultConfig {
  3. .....
  4. }
  5. packagingOptions {
  6. doNotStrip '*/mips/*.so'
  7. doNotStrip '*/mips64/*.so'
  8. }
  9. }

说明:若没有 res/drawable-xxxx/jpush_notification_icon 这个资源默认使用应用图标作为通知 icon,在 5.0 以上系统将应用图标作为 statusbar icon 可能显示不正常,用户可定义没有阴影和渐变色的 icon 替换这个文件,文件名不要变。

手动集成步骤

  • 解压缩 jpush-android—3.x.x-release.zip 集成压缩包。
  • 复制 libs/jcore-android-1.x.x.jar 到工程 libs/ 目录下。
  • 复制 libs/jpush-android-3.x.x.jar 到工程 libs/ 目录下。
  • 复制 libs/(cpu-type)/libjcore1xy.so 到你的工程中存放对应 cpu 类型的目录下。
  • 复制 res/ 中 drawable-hdpi, layout, values 文件夹中的资源文件到你的工程中 res/ 对应同名的目录下。
    说明 1:若没有 res/drawable-xxxx/jpush_notification_icon 这个资源默认使用应用图标作为通知 icon,在 5.0 以上系统将应用图标作为 statusbar icon 可能显示不正常,用户可定义没有阴影和渐变色的 icon 替换这个文件,文件名不要变。

说明 2:使用 android studio 的开发者,如果使用 jniLibs 文件夹导入 so 文件,则仅需将所有 cpu 类型的文件夹拷进去;如果将 so 文件添加在 module的libs 文件夹下,注意在 module 的 gradle 配置中添加一下配置:

  1. android {
  2. ......
  3. sourceSets {
  4. main {
  5. jniLibs.srcDirs = ['libs']
  6. ......
  7. }
  8. ......
  9. }
  10. ......
  11. }

配置 AndroidManifest.xml

根据 SDK 压缩包里的 AndroidManifest.xml 样例文件,来配置应用程序项目的 AndroidManifest.xml 。

主要步骤为:

  • 复制备注为 "Required" 的部分
  • 将标注为“您应用的包名”的部分,替换为当前应用程序的包名
  • 将标注为“您应用的 Appkey” 的部分,替换为在 Portal 上创建该应用后应用信息中的 Appkey,例如:9fed5bcb7b9b87413678c407
    小帖士

如果使用 android studio,可在 AndroidManifest 中引用 applicationId 的值,在 build.gradle 配置中 defaultConfig 节点下配置,如:

  1. defaultConfig {
  2. applicationId "cn.jpush.example" // <--您应用的包名
  3. ……
  4. }

在 AndroidManifest 中使用 ${applicationId} 引用 gradle 中定义的包名

AndroidManifest 示例

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="您应用的包名"
  4. android:versionCode="316"
  5. android:versionName="3.1.6"
  6. >
  7. <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23" />
  8. <!-- Required -->
  9. <permission
  10. android:name="您应用的包名.permission.JPUSH_MESSAGE"
  11. android:protectionLevel="signature" />
  12. <!-- Required -->
  13. <uses-permission android:name="您应用的包名.permission.JPUSH_MESSAGE" />
  14. <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
  15. <uses-permission android:name="android.permission.INTERNET" />
  16. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  17. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  18. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  19. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  20. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  21. <uses-permission android:name="android.permission.WRITE_SETTINGS" />
  22. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  23. <!-- Optional. Required for location feature -->
  24. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 用于开启 debug 版本的应用在 6.0 系统上的层叠窗口权限 -->
  25. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  26. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  27. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  28. <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
  29. <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
  30. <uses-permission android:name="android.permission.GET_TASKS" />
  31. <uses-permission android:name="android.permission.VIBRATE" />
  32. <application
  33. android:icon="@drawable/ic_launcher"
  34. android:label="@string/app_name"
  35. android:name="Your Application Name">
  36. <!-- Required SDK 核心功能-->
  37. <!-- 可配置 android:process 参数将 PushService 放在其他进程中 -->
  38. <service
  39. android:name="cn.jpush.android.service.PushService"
  40. android:enabled="true"
  41. android:exported="false" >
  42. <intent-filter>
  43. <action android:name="cn.jpush.android.intent.REGISTER" />
  44. <action android:name="cn.jpush.android.intent.REPORT" />
  45. <action android:name="cn.jpush.android.intent.PushService" />
  46. <action android:name="cn.jpush.android.intent.PUSH_TIME" />
  47. </intent-filter>
  48. </service>
  49. <!-- since 3.0.9 Required SDK 核心功能-->
  50. <provider
  51. android:authorities="您应用的包名.DataProvider"
  52. android:name="cn.jpush.android.service.DataProvider"
  53. android:exported="true"
  54. />
  55. <!-- since 1.8.0 option 可选项。用于同一设备中不同应用的 JPush 服务相互拉起的功能。 -->
  56. <!-- 若不启用该功能可删除该组件,或把 enabled 设置成 false ;App 不会被其他 App 拉起,但会拉起其他的 App。 -->
  57. <service
  58. android:name="cn.jpush.android.service.DaemonService"
  59. android:enabled="true"
  60. android:exported="true">
  61. <intent-filter >
  62. <action android:name="cn.jpush.android.intent.DaemonService" />
  63. <category android:name="您应用的包名"/>
  64. </intent-filter>
  65. </service>
  66. <!-- since 3.1.0 Required SDK 核心功能-->
  67. <provider
  68. android:authorities="您应用的包名.DownloadProvider"
  69. android:name="cn.jpush.android.service.DownloadProvider"
  70. android:exported="true"
  71. />
  72. <!-- Required SDK 核心功能-->
  73. <receiver
  74. android:name="cn.jpush.android.service.PushReceiver"
  75. android:enabled="true" >
  76. <intent-filter android:priority="1000">
  77. <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />
  78. <category android:name="您应用的包名"/>
  79. </intent-filter>
  80. <intent-filter>
  81. <action android:name="android.intent.action.USER_PRESENT" />
  82. <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
  83. </intent-filter>
  84. <!-- Optional -->
  85. <intent-filter>
  86. <action android:name="android.intent.action.PACKAGE_ADDED" />
  87. <action android:name="android.intent.action.PACKAGE_REMOVED" />
  88. <data android:scheme="package" />
  89. </intent-filter>
  90. </receiver>
  91. <!-- Required SDK 核心功能-->
  92. <activity
  93. android:name="cn.jpush.android.ui.PushActivity"
  94. android:configChanges="orientation|keyboardHidden"
  95. android:theme="@android:style/Theme.NoTitleBar"
  96. android:exported="false" >
  97. <intent-filter>
  98. <action android:name="cn.jpush.android.ui.PushActivity" />
  99. <category android:name="android.intent.category.DEFAULT" />
  100. <category android:name="您应用的包名" />
  101. </intent-filter>
  102. </activity>
  103. <!-- SDK 核心功能-->
  104. <activity
  105. android:name="cn.jpush.android.ui.PopWinActivity"
  106. android:configChanges="orientation|keyboardHidden"
  107. android:exported="false"
  108. android:theme="@style/MyDialogStyle">
  109. <intent-filter>
  110. <category android:name="android.intent.category.DEFAULT" />
  111. <category android:name="您应用的包名" />
  112. </intent-filter>
  113. </activity>
  114. <!-- Required SDK 核心功能-->
  115. <service
  116. android:name="cn.jpush.android.service.DownloadService"
  117. android:enabled="true"
  118. android:exported="false" >
  119. </service>
  120. <!-- Required SDK 核心功能-->
  121. <receiver android:name="cn.jpush.android.service.AlarmReceiver" />
  122. <!-- Required since 3.0.7 -->
  123. <!-- 新的 tag/alias 接口结果返回需要开发者配置一个自定的广播 -->
  124. <!-- 该广播需要继承 JPush 提供的 JPushMessageReceiver 类, 并如下新增一个 Intent-Filter -->
  125. <receiver
  126. android:name="自定义 Receiver"
  127. android:enabled="true"
  128. android:exported="false" >
  129. <intent-filter>
  130. <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
  131. <category android:name="您应用的包名" />
  132. </intent-filter>
  133. </receiver>
  134. <!-- User defined. 用户自定义的广播接收器-->
  135. <receiver
  136. android:name="您自己定义的 Receiver"
  137. android:enabled="true"
  138. android:exported="false">
  139. <intent-filter>
  140. <!--Required 用户注册 SDK 的 intent-->
  141. <action android:name="cn.jpush.android.intent.REGISTRATION" />
  142. <!--Required 用户接收 SDK 消息的 intent-->
  143. <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" />
  144. <!--Required 用户接收 SDK 通知栏信息的 intent-->
  145. <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" />
  146. <!--Required 用户打开自定义通知栏的 intent-->
  147. <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" />
  148. <!-- 接收网络变化 连接/断开 since 1.6.3 -->
  149. <action android:name="cn.jpush.android.intent.CONNECTION" />
  150. <category android:name="您应用的包名" />
  151. </intent-filter>
  152. </receiver>
  153. <!-- User defined. 用户自定义 Receiver 接收被拉起回调-->
  154. <!-- 自定义 Receiver 组件,继承cn.jpush.android.service.WakedResultReceiver类,复写onWake(int wakeType)或 onWake(Context context, int wakeType)方法以监听被拉起 -->
  155. <receiver android:name="xx.xx.xx.MyWakedResultReceiver">
  156. <intent-filter>
  157. <action android:name="cn.jpush.android.intent.WakedReceiver" />
  158. <category android:name="${applicationId}" />
  159. </intent-filter>
  160. </receiver>
  161. <!-- Required. For publish channel feature -->
  162. <!-- JPUSH_CHANNEL 是为了方便开发者统计 APK 分发渠道。-->
  163. <!-- 例如: -->
  164. <!-- 发到 Google Play 的 APK 可以设置为 google-play; -->
  165. <!-- 发到其他市场的 APK 可以设置为 xxx-market。 -->
  166. <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
  167. <!-- Required. AppKey copied from Portal -->
  168. <meta-data android:name="JPUSH_APPKEY" android:value="您应用的 Appkey"/>
  169. </application>
  170. </manifest>

配置和代码说明

必须权限说明

权限用途
You Package.permission.JPUSH_MESSAGE官方定义的权限,允许应用接收 JPush 内部代码发送的广播消息。
RECEIVE_USER_PRESENT允许应用可以接收点亮屏幕或解锁广播。
INTERNET允许应用可以访问网络。
WAKE_LOCK允许应用在手机屏幕关闭后后台进程仍然运行; 该权限从 JPush 3.1.5 版本开始变为可选权限,在 3.1.5 前的版本为必须权限。
READ_PHONE_STATE允许应用访问手机状态。
WRITE_EXTERNAL_STORAGE允许应用写入外部存储。
READ_EXTERNAL_STORAGE允许应用读取外部存储。
WRITE_SETTINGS允许应用读写系统设置项。
VIBRATE允许应用震动。 该权限从 JPush 3.1.5 版本开始变为可选权限,在 3.1.5 前版本为必须权限。
MOUNT_UNMOUNT_FILESYSTEMS允许应用挂载/卸载外部文件系统。
ACCESS_NETWORK_STATE允许应用获取网络信息状态,如当前的网络连接是否有效。

集成 JPush Android SDK 的混淆

  • 请下载 4.x 及以上版本的 proguard.jar, 并替换你 Android SDK "tools\proguard\lib\proguard.jar"

  • 请在工程的混淆文件中添加以下配置:

  1. -dontoptimize
  2. -dontpreverify
  3. -dontwarn cn.jpush.**
  4. -keep class cn.jpush.** { *; }
  5. -keep class * extends cn.jpush.android.helpers.JPushMessageReceiver { *; }
  6. -dontwarn cn.jiguang.**
  7. -keep class cn.jiguang.** { *; }
  • 2.0.5 ~ 2.1.7 版本有引入 gson 和 protobuf,增加排除混淆的配置。(2.1.8 版本不需配置)
  1. #==================gson && protobuf==========================
  2. -dontwarn com.google.**
  3. -keep class com.google.gson.** {*;}
  4. -keep class com.google.protobuf.** {*;}

添加代码

JPush SDK 提供的 API 接口,都主要集中在 cn.jpush.android.api.JPushInterface 类里。

基础API

  • init 初始化 SDK
  1. public static void init(Context context)
  • setDebugMode 设置调试模式

注:该接口需在 init 接口之前调用,避免出现部分日志没打印的情况。多进程情况下建议在自定义的 Application 中 onCreate 中调用。

  1. // You can enable debug mode in developing state. You should close debug mode when release.
  2. public static void setDebugMode(boolean debugEnalbed)

添加统计代码

调用示例代码(参考 example 项目)

  • init 只需要在应用程序启动时调用一次该 API 即可。

  • 以下代码定制一个本应用程序 Application 类。需要在 AndoridManifest.xml 里配置。请参考上面 AndroidManifest.xml 片断,或者 example 项目。

  1. public class ExampleApplication extends Application {
  2. @Override
  3. public void onCreate() {
  4. super.onCreate();
  5. JPushInterface.setDebugMode(true);
  6. JPushInterface.init(this);
  7. }
  8. }

测试确认

  • 确认所需的权限都已经添加。如果必须的权限未添加,日志会提示错误。
  • 确认 AppKey(在 Portal 上生成的)已经正确的写入 Androidmanifest.xml 。
  • 确认在程序启动时候调用了 init(context)接口
  • 确认测试手机(或者模拟器)已成功连入网络 + 客户端调用 init 后不久,如果一切正常,应有登录成功的日志信息
  • 启动应用程序,在 Portal 上向应用程序发送自定义消息或者通知栏提示。详情请参考管理 Portal
    • 在几秒内,客户端应可收到下发的通知或者正定义消息,如果 SDK 工作正常,则日志信息会如下:
  1. [JPushInterface] action:init
  2. .......
  3. [PushService] Login succeed!

如图所示,客户端启动分为 4 步:

  • 检查 metadata 的 appKey 和 channel,如果不存在,则启动失败
  • 初始化 JPush SDK,检查 JNI 等库文件的有效性,如果库文件无效,则启动失败
  • 检查 Androidmanifest.xml,如果有 Required 的权限不存在,则启动失败
  • 连接服务器登录,如果存在网络问题,则登陆失败,或者前面三步有问题,不会启动 JPush SDK

集成 FCM 通道

概述

Firebase 云消息传递(FCM)是由 Google 提供的推送服务,可以在服务器和用户设备之间建立可靠而且省电的连接,提高推送送达率。

JPush SDK 为了尽可能提高开发者在国外设备的推送送达率,对集成 FCM 的设备推送,自动切换到 FCM 通道。同时,为了保证 SDK 的易用性,原本 JPush 的所有接口调用逻辑都不用修改,JPush 会对自身支持的功能做兼容。

功能描述

  • FCM 集成完成后,在支持的设备上自动进行初始化。

  • FCM 可以与 JPush 和 其他三方通道 共存。

  • FCM 通道初始化后支持 tag/alias 这些 JPush 原有的功能,其它的 JPush 未支持的功能目前暂时还不可用。

集成方式

  • 开发者需要自行在 Firebase 平台注册账号和应用 id;
  • 开发者需要开通极光推送的 vip 服务,提供 Firebase 平台的应用信息,我们来开通通道;
    具体的开通方式和资费情况,请 联系商务

注1: 使用 FCM 通道需要 Google Play 服务为系统服务且版本不低于 11.0.4。

注2: 当设备网络环境为非中国时才会通过 FCM 通道进行推送。

进阶功能

请参考:

API:Android

技术支持

当出现问题时:

  • 请仔细阅读文档,查看是否有遗漏。 Android FAQ
  • 你可以到极光社区搜索类似问题
  • 给我们的 support 发邮件 support@jpush.cn
    为了更快速的解决问题,在寻求帮助时,请提供下列信息:

  • 你需要咨询的产品是 JPush,是否同时使用了极光其他的产品

  • 你所调用的是什么 API,所传参数,完整的报错信息,出现异常的时间点
  • 如果收不到消息,提供应用的 Appkey,消息的 Message ID,设备的 registration ID 信息
  • 如果是 SDK 问题请提供对应的 SDK 版本和完整的日志记录,日志信息请使用 TXT 文件上传
  • 出现异常的设备是 Android ,列出具体的机型和系统