极光推送 JPush 教程

现在很多 Android 或者 iOS 应用都需要服务器推送,有很多第三方应用可以实现此功能,如 Firebase Cloud Messaging (原 Google Cloud Messaging) 和 Apple Push Notifications。由于 Google 官方的推送服务 Firebase Cloud Messaging 不能再中国使用,所以在此介绍极光推送的使用。

准备工作

  1. 注册成为 JPush 开发者
    JPush 开发者服务注册账号并登陆。
  2. 创建应用
    点击 “应用管理” 页面的 “创建应用” 按钮。填写应用名称,应用图标,Android 应用包名(不可更改),iOS 开发证书及密码,iOS 生产证书及密码。
  3. 记录 APPKey 和 Master Secret
    点击刚创建的应用详情页面,记录 APPKey 和 Master Secret

服务器端

本文使用 Python 作为服务器脚本语言。
官方文档:Python SDK
SDK 下载:Python SDK v3.2.4
官方源码:jpush-api-python-client
官方 API:jpush python api
官方 API:REST Push API

环境配置

pip 方式:pip install jpush
easy_install 方式:easy_install jpush
使用源码方式:python setup.py install

服务器设置

新建 conf.py 文件:

1
2
3
# please put your app_key and master_secret here
app_key = u'your app_key'
master_secret = u'your master_secret'

服务端主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from conf import app_key, master_secret
_jpush = jpush.JPush(app_key, master_secret) #初始化jpush
_jpush.set_logging("DEBUG") #设置日志
push = _jpush.create_push() #初始化push
push.platform = jpush.all_ #设置推送所有平台
push.platform = jpush.platform(*types) #设置推送指定平台,关键字为"android", "ios","winphone"
push.audience = jpush.registration_id(*reg_ids) #根据注册id指定推送设备
push.audience = jpush.alias(*alias) #根据别名指定推送设备,别名在开发者服务平台中设置
push.audience = jpush.tag(*tag) #根据标签指定推送设备,标签在开发者服务平台中设置,多个标签之间是 OR 的关系,即取并集。
push.audience = jpush.tag_and(*tag_ands) #根据标签指定推送设备,标签在开发者服务平台中设置,多个标签之间是 AND 关系,即取交集。
push.notification = jpush.notification(alert=None, ios=None, android=None, winphone=None) #指定通知内容,如果下方各平台定义了alert,则覆盖这里的定义
ios = jpush.ios(alert=None, badge=None, sound=None, content_available=False, extras=None, sound_disable=False) #指定通知内容,声音,角标,唤醒,扩展字段
android = jpush.android(alert, title=None, builder_id=None, extras=None) #指定通知内容,标题,样式,扩展字段
push.message = jpush.message(msg_content, title=None, content_type=None, extras=None) #指定消息内容
push.smsmessage = jpush.smsmessage(content,delay_time) #指定短信内容和延迟时间(单位为秒,不能超过24小时。设置为0,表示立即发送短信。该参数仅对android平台有效,iOS 和 Winphone平台则会立即发送短信)
result = push.send() #执行推送

Android 客户端

官方集成文档:Android SDK 集成指南
官方 API:Android SDK API
SDK 下载:Android SDK
目前 SDK 只支持 Android 2.3 或以上版本的手机系统。富媒体信息流功能则需 Android3.0 或以上版本的系统。

jcenter 自动集成步骤

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

  1. 确认 android studio 的 Project 根目录的主 gradle 中配置了 jcenter 支持。(新建 project 默认配置就支持)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    buildscript {
    repositories {
    jcenter()
    }
    ......
    }

    allprojects {
    repositories {
    jcenter()
    }
    }
  2. 在 module 的 gradle 中添加依赖和 AndroidManifest 的替换变量。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    android {
    ......
    defaultConfig {
    applicationId "com.xxx.xxx" //JPush上注册的包名.
    ......

    ndk {
    //选择要添加的对应cpu类型的.so库。
    abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'
    // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
    }

    manifestPlaceholders = [
    JPUSH_PKGNAME : applicationId,
    JPUSH_APPKEY : "你的appkey", //JPush上注册的包名对应的appkey.
    JPUSH_CHANNEL : "自定义渠道名称", //用户渠道统计的渠道名称
    ]
    ......
    }
    ......
    }

    dependencies {
    ......

    compile 'cn.jiguang.sdk:jpush:x.x.x' // 此处为JPush的版本号
    compile 'cn.jiguang.sdk:jcore:x.x.x' // 此处为JCore的版本号
    ......
    }

    注:如果在添加以上 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

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

初始化 SDK

在主 activity 中:

  1. import cn.jpush.android.api.JPushInterface;
  2. 在 onCreate 函数中
    1
    2
    3
    JPushInterface.setDebugMode(true); //开启调试
    JPushInterface.init(this); //初始化
    rid = JPushInterface.getRegistrationID(getApplicationContext()); //获取Registration ID

接收推送消息 Receiver

JPush SDK 收到推送,通过广播的方式,转发给开发者 App,这样开发者就可以灵活地进行处理。
这个动作不是必须的。用户有需要才定义 Receiver 类来处理 SDK 过来的广播。
如果不做这个动作,即不写自定义 Receiver,也不在 AndroidManifest.xml 里配置这个 Receiver,则默认的行为是:

  1. 接收到推送的自定义消息,则没有被处理
  2. 可以正常收到通知,用户点击打开应用主界面
    ### 接受广播
    如果全部类型的广播都接收,则需要在 AndroidManifest.xml 里添加如下的配置信息:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <receiver
    android:name="Your Receiver"
    android:enabled="true">
    <intent-filter>
    <action android:name="cn.jpush.android.intent.REGISTRATION" />
    <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" />
    <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" />
    <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" />
    <action android:name="cn.jpush.android.intent.NOTIFICATION_CLICK_ACTION" />
    <action android:name="cn.jpush.android.intent.CONNECTION" />
    <category android:name="You package Name" />
    </intent-filter>
    </receiver>

    ### 开发者自定义 Receiver 代码示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    package name;

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.util.Log;

    import cn.jpush.android.api.JPushInterface;

    public class MyReceiver extends BroadcastReceiver {
    private static final String TAG = "JPush";

    public void onReceive(Context context, Intent intent) {
    Bundle bundle = intent.getExtras();
    Log.d(TAG, "[MyReceiver] onReceive - " + intent.getAction());

    if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
    String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
    Log.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
    //send the Registration Id to your server...

    } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
    Log.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));

    } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
    Log.d(TAG, "[MyReceiver] 接收到推送下来的通知: " + bundle.getString(JPushInterface.EXTRA_ALERT) +
    ", extras: " + bundle.getString(JPushInterface.EXTRA_EXTRA));
    int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
    Log.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId);

    } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
    Log.d(TAG, "[MyReceiver] 用户点击打开了通知");

    //打开自定义的Activity
    Intent i = new Intent(context, 需要跳转的activity名称.class);
    i.putExtras(bundle);
    //i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP );
    context.startActivity(i);

    } else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {
    Log.d(TAG, "[MyReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));
    //在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等..

    } else if(JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {
    boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);
    Log.w(TAG, "[MyReceiver]" + intent.getAction() +" connected state change to "+connected);
    } else {
    Log.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction());
    }
    }
    }