作者 : octopus_truth

转载请注明出处http://blog.csdn.net/shulianghan/article/details/45046283

推送技术产生场景 :

-- 服务器端主动性 : 客户端与服务器交互都是客户端主动的, 服务器一般不能主动与客户端进行数据交互, 因为服务器端无法得知客户端的 IP 地址 及 状态;

-- 数据实时性 : 如果服务器端有紧急数据要传递给客户端, 就必须主动向客户端发送数据;

-- 基本原理 : 使客户端实时获取服务器端消息, Pull 方式, 小周期轮询, 费电费流量; 另一个就是 Push 方式, 服务器端向客户端主动推送数据, 可以省电省流量;

示例代码下载http://download.csdn.net/detail/han1202012/8636005

一. 推送原理

1. Android 推送原理简介

(1) SMS 方式推送

SMS 推送 :

-- SMS : Short Message Service 缩写, 即短信服务;

-- 实现方式 : 服务器端向手机端发送短信, 手机监听短信广播, 然后将拦截的短信信息进行显示;

-- 优点 : 省电, 省流量, 在没有网络的偏远地点也能接收到推送消息;

-- 缺点 : 费钱, 一毛钱一条;

(2) 轮询 方式推送

轮询推送 :

-- 实现方式 : 周期性主动获取网络中的数据;

-- 缺点 : 费电, 费流量;

(3) 长链接 方式推送

长链接推送 : 主流方法;

-- 实现方式 : 手机端与服务器端建立一条长时间的数据流链接, 手机客户端一直等待服务器端的数据;

-- 优点 : 有一条长链接, 有数据的时候才发送数据, 没有时不消耗流量, 比较省流量;

-- 缺点 : 由于要保存一条长链接, 比较费电; 在网络不稳定的情况下, 推送容易失败;

2. Android 推送解决方案简介

(1) C2DM 推送 (Google)

C2DM 推送简介 : 全称 Cloudto Device Messaging, Google 提供的 推送解决方案;

-- 运行方式 : 提供一个轻量级机制, 允许服务器通知应用程序, 主动与客户端进行数据交互, 处理消息排队, 并向运行于目标设备的应用程序分发消息;

-- 优点 : Google 提供的原生框架, 无需在应用中添加第三方代码 和 部署服务器端;

-- 缺点 : 1.该推送依赖 Google 服务器, 需要绑定 Google 帐号, 目前在中国 Google 被屏蔽, 无法使用; 2. 许多手机厂商去掉了软件中的该模块;

-- 运行机制图 :

(2) MQTT 推送 (IBM)

MQTT 推送简介 : MQTT 是轻量级的消息发布|订阅协议,

-- 优点 : 省电, 省流量, 轻量级, 有 C++ 版的服务器端组件 RSMB;

-- 缺点 : RSMB 不开源, 部署成本高, 比较复杂;

-- IBM相关MQTT官网http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006 ;

RSMB 服务器端 : 全称 Really Small Message Broker, IBM 提供;

-- 工作方式 : 在服务器端, 接收消息, 并将 消息 传输给指定移动设备;

-- 地址 http://www.alphaworks.ibm.com/tech/rsmb ;

MQTT 推送示例 :

-- 客户端https://github.com/tokudu/AndroidPushNotificationsDemo ;

-- 服务器端 PHP : https://github.com/tokudu/PhpMQTTClient ;

(3) 基于 XMPP 的 AndroidPN 推送 (开源)

XMPP 推送简介 :

-- XMPP 简介 : 全称 Extensible Messaging and Presence Protocol (可扩展通讯和表示协议), 基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测, 该协议允许因特网用户向因特网上的其他任何人发送即时消息;

-- AndroidPN : 基于 XMPP 协议开发的 Java 开源 Android 推送通知实现, 包含了完整的客户端 和 服务器端;

-- 项目主页http://sourceforge.net/projects/androidpn/ ;

-- 原理图 :

AndroidPN 缺陷 : 如果使用该框架进行推送, 需要在了解 XMPP 和 anroidPN 基础上进行大量的二次开发;

-- 连接中断 : 连接时间过长, 连接会中断, 收不到消息;

-- 稳定性差 : 该框架不是很稳定;

-- 纠错机制 : 消息推送出去后, 不检查是否推送到客户端, 推送出去就不管了;

3. 推送 4s 评价标准

4S 标准Safe(安全), Stable(稳定), Save(省电省流量省成本), Slim(体积小);

(1) Safe (安全)

推送安全标准 :

-- 透明传输 : 只负责点对点的传输的质量, 不关心中间的传输介质 与 传输业务逻辑 协议等;

-- 加密方案 : 信息需要加密, 另外推送的 ID 系统需要独立与后台已有的 ID 系统;

(2) Stable (稳定)

服务器稳定 : 长链接方案对服务器开销要求很高, 服务器端开发难度很大;

-- 在线峰值 : 同时在线连接数到达100万的稳定性;

-- 并发时延 : 高并发时的消息平均延迟, 一分钟处理 100万 条数据;

-- 服务器稳定 : 稳定性时延占总时间的 99.9%, 有备份和负载均衡的机制;

客户端稳定 : 中国网络状况复杂, 手机长时间联网比较难, 稳定性比较难, 开发时要考虑每个省的每个运营商, 每款手机的机型;

-- 联网时间 : 每日联网时间 23.5 小时以上;

-- 消息到达率 : 消息收到后 9 小时内客户端的消息到达率;

(3) Save (节省)

节省评判 :

-- 电量节省 : 注意 CPU 休眠率, 服务短待机时间百分比评判;

-- 流量节省 : 处理协议 和 冗余数据包, 使用空载待机月流量评判;

-- 成本节省 : 单服务器同时承载连接数, 同时承载连接数越多, 成本越低, 个推单服务器连接 300 万(业内顶尖水平);

(4) Slim (体积小)

集成 SDK 大小 : 客户端推送的 SDK 的大小尽量小, 一般要小于 300K;

二. 极光推送概述

1. 功能概述

极光推送基本功能 : 主动 即时 的向用户发起交互, 可以发送聊天消息;

-- 作用 : 通过向 精准 的目标用户推送 有价值 的消息, 可以提供用户忠诚度, 提高留存率;

(1) 推送方式

推送方式简介 :

-- 通知 : 推送文本内容, 展示在通知栏中;

-- 自定义消息 : 推送自定义消息, 给用户自行处理;

-- 富媒体 : 推送 HTML 页面内容;

(2) 推送目标

推送目标简介 :

-- 广播推送 : 向所有用户发送广播消息;

-- 标签推送 : 根据用户设置的标签分组, 向某一组推送消息;

-- 别名推送 : 客户端绑定用户别名, 向单个用户推送信息;

(3) 用户分群

用户分群简介 : 可以根据 JPush 提供的 多条件组合, 对用户进行群组划分, 实现 实时筛选推送;

(4) 推送历史

推送历史简介 : 通过 WEB 或者 API 发出的推送, 都可以在推送历史记录中查询到, 并可以实时显示推送结果;

2. 推送框架

推送框架 :

-- 推送数据源 : 自己开发的服务器端 或者 使用 极光推送官网的 WEB 后台;

-- JPush API : 部署在服务器端, 开发者的服务器端发起推送时, 将数据传到 JPush API 中, 然后再向下传递;

-- 建立长链接 : 集成 JPush 的 SDK 客户端启动后会建立一个到 JPush Cloud 的长链接, 提供 App 永远在线的能力;

-- 原理图 :

3. 极光推送原理

参考文章(极光推送官方博客) : http://blog.jpush.cn/jpush_wireless_push_principle/ ;

(1) 客户端原理

IP地址 分配原理 :

-- IP 地址有限 : IPv4 的 IP 地址数量有限, 运营商要动态地为 手机分配 IP 地址, 这些 IP 地址都是运营商的内网 IP;

-- 网络地址转换 (NAT) : 全称 Network Address Translation, 网关维护一个外网 IP 地址, 与 内网 IP 地址对应;

-- 外网 IP 不固定 : 由于运营商持有的外网 IP 数量有限, 需要动态的分配给接入运营商的用户, 因此在手机一段时间没有数据传输时会将该手机分配的外网 IP 地址收回, 分配给其它用户;

-- 解决方案 : Android 手机端想要保持长链接, 首先外网 IP 地址不能变, 不能让运营商收回 这个 IP 地址;

Android 手机端实现方案 :

-- 心跳 : 为了长时间保持外网 IP, 需要客户端定期发送心跳给运营商, 以便刷新 NAT 列表;

-- Timer 定时方法 : 该类计划循环执行定时任务, 但是使用该类会使 CPU 保持唤醒状态, 比较费电;

-- AlarmManager 定时方法 : 该类封装了 Android 手机的 RTC 硬件时钟模块, 可以在 CPU 休眠时正常运行, 定时任务执行时再唤醒 CPU, 这样做到了电量节省;

(2) 服务器原理

C10K 问题 : 单台服务器解决 同时保持一万长链接的性能问题;

4. Android SDK 简介

Android SDK 本质 : JPush SDK 集成到 Android APP 中后, 作为一个 Service 在 Android 端长期运行, 始终与 服务器端 保持者长链接, 相当与永远在线;

(1) 多平台支持

多平台支持 :

-- 手机芯片类型 : 一般的手机是 ARM 芯片, 但是有些手机是 MIPS 芯片 或者 x86 芯片;

-- so 库支持 : 每个 CPU 芯片类型对应的 so 库, 都需要特殊编译, 无法跨平台调用, 如 ARM 平台的 so 库在 x86 平台就无法运行;

(2) 电量与流量说明

流量消耗 : JPush 的协议是自定义的, 协议的数据量经过了精简, 流量消耗非常少;

电量消耗 : JPush 心跳保持连接时可以在 CPU 不唤醒的情况下执行, 减少了不必要的代码运行, 电量非常节省;

(3) 相关库说明

JPush 依赖库 :

-- .so 依赖库内容 : JPush 需要一个 so 动态库, 该库是 C 语言编写, 在 Linux 下进行交叉编译而来, 可以在 ARM 芯片的手机上运行;

-- jar 依赖库内容 : 对 Java 代码的封装;

三. 极光推送简单 Demo

Demo 概述 : JPush 官方提供了一个简单 Demo, 向我们演示了 JPush 基本的推送流程, 基本步骤分为下面几块, 即

-- Web 配置操作部分 : 包括 注册开发者帐号, 创建应用;

-- 下载手机示例 : 下载系统自动生成的 Android 应用示例;

-- 发送推送指令 : 在 Web 端发送推送指令, 手机端接收该指令;

-- 官方地址 : 关于该模块详细信息可参考官方文档, http://docs.jpush.io/guideline/android_3m/;

1. Web 配置操作

(1) 帐号创建

该步骤就不再赘述, 普通的帐号注册即可;

(2) 创建应用

创建应用步骤 :

-- 创建应用界面 https://www.jpush.cn/common/apps ;

-- 创建应用 : 点击 创建应用 按钮即可;

-- 配置应用信息 : 输入应用名称, 上传一个图标, 然后填写一个包名, JPush 系统会在后台根据你输入的包名生成的推送的 Android 应用 Demo, 该 Demo 包含了该配置的信息;

查看应用设置界面 :

2. 下载导入 Android 应用源码

(1) 下载 Android 应用源码

下载源码 : 在应用设置的 Android 模块, 有 "下载 Android Example" 按钮, 点击该按钮即可下载 Android 应用;

(2) 导入 Android 应用源码

将下载后的源码解压, 不用任何修改, 即可导入到应用中运行;

3. 发送推送

(1) 不初始化推送无效

直接在后台推送 : 我们在 Android 手机界面不做任何操作, 直接在网页后台推送消息;

-- 发送通知 : 在应用的 "推送" 模块, 点击发送通知按钮;

-- 输入推送内容 : 输入任意推送内容 "Jpush Demo Send By octopus 1.", 点击页面最下方的 "立即发送" 按钮;

-- 对话框选择 : Web 界面会弹出对话框, 提示是否发送, 选 "发送吧" 即可;

-- 查看推送结果 : 点击之后又弹出对话框, 点击 "去看看" 可以查看推送结果;

-- 推送结果分析 : 点击上面的 "去看看" 可以查看推送结果, 点击 "推送历史" 按钮, 也可一查看推送结果; 由于我们没有在 客户端进行初始化, 因此推送没有成功;

(2) 初始化后推送

初始化之后推送 :

-- 手机端初始化 : 点击手机端的 "initPush" 按钮, 进行初始化;

-- 发送消息 : 发送 "Jpush Demo Send By octopus 2." 消息, 此时连上一次推送的消息也送达, 网络不同会延迟一定时间;

-- 查看发送结果 : 此时显示的推送, 两次都成功了;

(3) 停止 和 恢复 推送功能

停止恢复推送功能 : 当点击停止推送 "stopPush" 按钮时, 推送手机端就不会再接收推送内容, 当点击恢复推送时, 会将期间积攒的所有推送内容一次性推送到手机中;

四. Android 应用集成 JPush

1. 依赖库拷贝

(1) SDK 简介

SDK 下载 : 最新的 SDK 压缩包 Jpush-Android-sdk-1.7.3.zip ;

-- JPush SDK 下载页面 : http://docs.jpush.io/resources/ ;

-- Android SDK 下载地址 : https://www.jpush.cn/downloads/sdk/android/ ;

详细文件说明 : 将 Jpush-Android-sdk-1.7.3.zip 解压, 解压后的目录是 Jpush-Android-sdk;

-- 查看文档目录 : 使用 tree -L 3 命令, 查看深度为 3 的路径结构;

octopus@octopus:~/JPush/Jpush-Android-sdk$ tree -L 3
.
├── AndroidManifest.xml
├── ChangeLog.txt
├── doc
│   └── Jpush-sdk-集成指南.pdf
├── example
│   ├── AndroidManifest.xml
│   ├── libs
│   │   ├── armeabi
│   │   ├── armeabi-v7a
│   │   └── jpush-sdk-release1.7.3.jar
│   ├── proguard-project.txt
│   ├── project.properties
│   ├── res
│   │   ├── drawable-hdpi
│   │   ├── drawable-ldpi
│   │   ├── drawable-mdpi
│   │   ├── drawable-xhdpi
│   │   ├── layout
│   │   ├── values
│   │   └── values-zh
│   └── src
│       └── com
└── libs
    ├── armeabi
    │   └── libjpush173.so
    ├── armeabi-v7a
    │   └── libjpush173.so
    └── jpush-sdk-release1.7.3.jar

-- AndroidManifest.xml (配置文件) : 这是 Android 应用的主要配置文件示例;

-- ChangeLog.txt (升级说明) : SDK 版本升级的说明;

-- doc (文档) : doc 目录下 有个 "Jpush-sdk-集成指南.pdf" 文档, 这是集成 JPush 文档;

-- example (代码示例) : example 明显是个 Android 示例 demo;

-- libs (依赖库) : Android 应用中相关库, 放在这个目录中, libjpush173.so 是依赖的 C 底层库, jpush-sdk-release1.7.3.jar 是依赖的 Java 库;

(2) 拷贝 依赖库 到 Android 应用中

执行过程 :

-- 创建应用 : 创建一个空应用, 注意应用最小版本应大于 2.1, 否则不能支持极光推送, 应用的包名为 cn.org.octopus.jpush.demo 即可, 不用在后台另外创建一个

-- 拷贝依赖库 : 在工程根目录下创建一个 libs 目录, 拷贝 jpush-sdk-release1.7.3.jar 到 libs 目录中, 将 armeabi/libjpush173.so 和 armeabi-v7a/libjpush173.so 拷贝到 libs 目录, 注意要连文件夹一起拷贝, 拷贝完后如下图;

2. 配置 AndroidManifest.xml 文件

(1) 权限配置

JPush 定义权限 : JPush 定义了一个权限, 允许应用接收 JPush 代码发送的广播消息, You Package.permission.JPUSH_MESSAGE, 注意要使用你的包名替换其中的 Your Package;

<!-- Required -->
    <permission android:name="Your Package.permission.JPUSH_MESSAGE" android:protectionLevel="signature" />

用户权限 :

<!-- Required -->
    <uses-permission android:name="You Package.permission.JPUSH_MESSAGE" />
    <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

可选用户权限

    <!-- Optional. Required for location feature -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

(2) 配置 JPush 服务

JPush 服务 :

-- 推送服务 :

        <!-- Required -->
        <service
            android:name="cn.jpush.android.service.PushService"
            android:enabled="true"
            android:exported="false" >
            <intent-filter>
                <action android:name="cn.jpush.android.intent.REGISTER" />
                <action android:name="cn.jpush.android.intent.REPORT" />
                <action android:name="cn.jpush.android.intent.PushService" />
                <action android:name="cn.jpush.android.intent.PUSH_TIME" />
            </intent-filter>
        </service>

-- 下载服务 :

        <!-- Required SDK核心功能-->
        <service
            android:name="cn.jpush.android.service.DownloadService"
            android:enabled="true"
            android:exported="false" >
        </service>

(3) 配置 JPush 广播接收者

JPush 广播接收者配置 :

-- 推送接收者 :

<!-- Required -->
        <receiver
            android:name="cn.jpush.android.service.PushReceiver"
            android:enabled="true" >
          <intent-filter android:priority="1000"> <!--since 1.3.5 -->
                <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" /> <!--since 1.3.5 -->
                <category android:name="Your Package" /> <!--since 1.3.5 -->
            </intent-filter> <!--since 1.3.5 -->
            <intent-filter>
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <data android:scheme="package" />
            </intent-filter>
        </receiver>

-- 时钟相关接收者

        <!-- Required SDK核心功能-->
        <receiver android:name="cn.jpush.android.service.AlarmReceiver" />

(4) 配置 渠道 和 推送标识

渠道 和 AppKey 配置 :

        <!-- Required. For publish channel feature -->
        <!-- JPUSH_CHANNEL 是为了方便开发者统计APK分发渠道。-->
        <!-- 例如: -->
        <!-- 发到 Google Play 的APK可以设置为 google-play; -->
        <!-- 发到其他市场的 APK 可以设置为 xxx-market。 -->
        <!-- 目前这个渠道统计功能的报表还未开放。-->
        <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
        <!-- Required. AppKey copied from Portal -->
        <meta-data android:name="JPUSH_APPKEY" android:value="Your AppKey"/> 

(5) 最终的配置文件

配置好的文件 :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.org.octopus.jpush.demo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="19" />

    <permission android:name="cn.org.octopus.jpush.demo.permission.JPUSH_MESSAGE" android:protectionLevel="signature" />

    <uses-permission android:name="cn.org.octopus.jpush.demo.permission.JPUSH_MESSAGE" />
    <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name="cn.jpush.android.service.PushService"
            android:enabled="true"
            android:exported="false" >
            <intent-filter>
                <action android:name="cn.jpush.android.intent.REGISTER" />
                <action android:name="cn.jpush.android.intent.REPORT" />
                <action android:name="cn.jpush.android.intent.PushService" />
                <action android:name="cn.jpush.android.intent.PUSH_TIME" />
            </intent-filter>
        </service>

        <service
            android:name="cn.jpush.android.service.DownloadService"
            android:enabled="true"
            android:exported="false" >
        </service>

        <receiver
            android:name="cn.jpush.android.service.PushReceiver"
            android:enabled="true" >
          <intent-filter android:priority="1000">
                <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />
                <category android:name="cn.org.octopus.jpush.demo" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <data android:scheme="package" />
            </intent-filter>
        </receiver>

        <receiver android:name="cn.jpush.android.service.AlarmReceiver" />

        <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
        <meta-data android:name="JPUSH_APPKEY" android:value="fd5eebd555ca4a5a80c4b3d8"/> 

    </application>

</manifest>

3. 推送测试

后台推送 :

-- 控制台地址 : https://www.jpush.cn/common/apps/ ;

-- 发起推送 : 进入控制台, 点击对应的应用, 进入推送页面;

-- 查看结果 :

-- 推送统计 :

五. JPush 相关 API

1. 初始化 停止 恢复 推送

推送控制方法 :

-- 初始化推送 : JPushInterface.init(Context context), 初始化之后才能接收推送消息;

-- 恢复推送 : JPushInterface.resumePush(Context context), 停止推送后, 调用该方法, 即可恢复推送;

-- 停止推送 : JPushInterface.stopPush(Context context), 调用该方法之后, 手机便收不到推送信息了;

代码示例 :

	public void onClick(View view) {
		int id = view.getId();
		switch (id) {
		case R.id.init_jpush:
			//初始化 JPush, 初始化之后才可以进行推送, 否则推送失败
			JPushInterface.init(this);
			//设置调试模式, 可以在 LogCat 中查看 JPush 日志
			JPushInterface.setDebugMode(true);
			break;
		case R.id.start_jpush:
			//恢复推送
			JPushInterface.resumePush(getApplicationContext());
			break;
		case R.id.stop_jpush:
			//停止推送
			JPushInterface.stopPush(getApplicationContext());
			break;

		default:
			break;
		}
	}

界面效果及说明 :

-- 界面效果 :

-- 按钮说明 : 点击 "初始化" 按钮就可以接收推送消息, 点击 "停止推送" 按钮手机停止接收消息推送, 点击 "恢复推送" 即开始接收推送消息;

2. 根据 别名 和 标签 分组推送

参考文档http://docs.jpush.cn/pages/viewpage.action?pageId=557241

(1) 概念介绍

别名 :

-- 作用 : 别名用于代表安装了应用的用户, 每个用户对应着一个别名;

-- 用户与别名对应性 (多对一) : 每个用户只能指定一个别名, 一个别名可以同时指定给多个用户, 给别名发消息时, 会同时给所有设置该别名的用户发消息;

标签 :

-- 作用 : 方便开发者根据标签发送推送消息;

-- 用户与标签对应性(多对多) : 一个用户可以有多个标签, 一个标签可以设置给多个用户;

(2) 设置别名标签接口方法

设置别名与标签方法 :

-- 方法接口 :

public static void setAliasAndTags(
	Context context, 		//上下文对象
	String alias, 			//别名, 只能设置一个别名
	Set<String> tags, 		//标签集合, 可设置多个标签
	TagAliasCallback callback)	//回调接口, 其中有一个 gotResult 接口方法, 系统回传入错误码给 responseCode 参数

-- 别名设置说明 : a. 设置 null(没有地址) 即不设值值; b. 设置 "" (初始化后) 即清空之前的设置; c. 设置会覆盖之前的设置; d. 长度 40字节 UTF8 编码;

-- 标签设置说明 : a. 设置 null(没有地址) 即不设值值; b. 设置 空集合(没有数据, 已经初始化) 即清空之前的设置; c. 设置会覆盖之前的设置; d. 每个标签长度 40字节 UTF8 编码, 最多 100 个标签;

设置别名方法 :

-- 方法接口 :

public static void setAlias(
	Context context, 		//上下文对象
	String alias, 			//别名内容
	TagAliasCallback callback)	//回调接口

-- 参数说明 : 该参数与 setAliasAndTags 方法参数相同;

设置标签方法 :

-- 方法接口 :

public static void setTags(
	Context context,
	Set<String> tags,
	TagAliasCallback callback)

-- 参数说明 : 该参数与 setAliasAndTags 方法参数相同;

过滤无效标签 : 感觉这纯属 JPush API 定义缺陷, 这个应该对我们隐藏才对;

-- 方法接口 :

public static Set<String> filterValidTags(Set<String> tags)

-- 作用 : 设置标签时如果 标签Set集合  中有一个是无效的, 那么整个设置都无效, 应该是设计缺陷, 后期修补 BUG 的权益之际;

回调接口 : TagAliasCallback 回调接口;

-- 方法接口 :

public void gotResult(
	int responseCode, 	//错误码
	String alias, 		//别名
	Set<String> tags);	//标签集合

代码示例 :

-- 设置方法代码 :

			String alias = set_alias.getText().toString();
			String tag = set_tag.getText().toString();
			Set<String> set = new HashSet<String>();
			set.add(tag);
			JPushInterface.setAliasAndTags(
					getApplicationContext(),
					alias,
					set,
					this);
			Log.i(TAG, "已设置别名 与 标签");

-- 回调方法

	@Override
	public void gotResult(int arg0, String arg1, Set<String> arg2) {
		Log.i(TAG, "错误码 : " + arg0 + " , 别名 : " + arg1);
	}

-- 手机端设置 :

-- 后台发送极光推送


-- 设置标签 :

-- 标签报错 : 如果设置的标签没有手机注册, 会出现如下报错;

-- 推送结果 :

-- 推送通知消息 :

3. 根据 RegistrationID 进行单机推送

参考文档 : http://docs.jpush.cn/pages/viewpage.action?pageId=8814639

(1) 概念介绍

RegistrationID 简介 : 应用第一次注册到 JPush 后台时, 会生成一个唯一的设备标识 RegistrationID, 每个设备不重复;

(2) 获取 RegistrationID

方法接口 :

//SDK 初次注册成功后,开发者通过在自定义的 Receiver 里监听 Action - cn.jpush.android.intent.REGISTRATION 来获取对应的 RegistrationID。注册成功后,也可以通过此函数获取

public static String getRegistrationID(Context context)

-- 获取 RegistrationID 代码

			//获取 RegistrationID
			String registrationid = JPushInterface.getRegistrationID(getApplicationContext());
			tv_registrationid.setText("RegistrationID : " + registrationid);

-- 界面示例 :

-- 后台推送设置 :

4. 清除通知

清除通知简介 :

-- 方法接口 :

public static void clearAllNotifications(Context context);

-- 代码示例 :

case R.id.clear_notification:
			//清除所有通知
			JPushInterface.clearAllNotifications(getApplicationContext());
			break;

-- 效果 : 在后台发送一条消息, 点击清除按钮, 所有的推送通知都清除;

5. 推送时间限制

(1) 设置允许推送时间

方法接口 :

public static void setPushTime(
	Context context, 	//上下文对象
	Set<Integer> weekDays, 	//允许接收推送的 一周天数
	int startHour, 		//开始时间
	int endHour)		//结束时间

-- 代码示例

Set<Integer> days = new HashSet<Integer>();
days.add(1);
days.add(2);
days.add(3);
days.add(4);
days.add(5);
JPushInterface.setPushTime(getApplicationContext(), days, 10, 23);

(2) 设置禁止推送时间

方法接口 :

public static void setSilenceTime(
	Context context, 	//上下文对象
	int startHour, 		//开始时间-小时
	int startMinute, 	//开始时间-分钟
	int endHour, 		//结束时间-小时
	int endMinute)		//结束时间-分钟

-- 代码示例

JPushInterface.setSilenceTime(getApplicationContext(), 22, 30, 8, 30);

作者 : octopus_truth

转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/45046283

【Android应用开发】 推送原理解析 极光推送使用详解 (零基础精通推送)的更多相关文章

  1. Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送

    Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送, ...

  2. Android Studio一直显示Building“project name”Gradle project info问题详解

    关注我,每天都有优质技术文章推送,工作,学习累了的时候放松一下自己. 本篇文章同步微信公众号  欢迎大家关注我的微信公众号:「醉翁猫咪」 Android Studio一直显示 Building&quo ...

  3. 数据结构图文解析之:AVL树详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  4. Nginx 负载均衡原理简介与负载均衡配置详解

    Nginx负载均衡原理简介与负载均衡配置详解   by:授客  QQ:1033553122   测试环境 nginx-1.10.0 负载均衡原理 客户端向反向代理发送请求,接着反向代理根据某种负载机制 ...

  5. Jquery遍历筛选数组的几种方法和遍历解析json对象|Map()方法详解

    Jquery遍历筛选数组的几种方法和遍历解析json对象|Map()方法详解 一.Jquery遍历筛选数组 1.jquery grep()筛选遍历数组 $().ready( function(){ v ...

  6. Android中微信抢红包插件原理解析和开发实现

    一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  7. Android View 的事件分发原理解析

    作为一名 Android 开发者,每天接触最多的就是 View 了.Android View 虽然不是四大组件,但其并不比四大组件的地位低.而 View 的核心知识点事件分发机制则是不少刚入门同学的拦 ...

  8. 无需开发,IT事件接入钉钉的方法详解

    1.市场在拥抱钉钉 虎嗅8月30日发表了一篇文章<为什么有很多企业沉迷钉钉无法自拔>,有兴趣的可以去看看,下附文章链接. 文章不短,其中有一部分阐述了:钉钉抓住以人为核心的"智能 ...

  9. monkey 原理,环境搭建、命令详解

    一.monkey测试的相关的原理 monkey测试的原理就是利用socket通讯的方式来模拟用户的按键输入,触摸屏输入,手势输入等,看设备多长时间会出异常.当Monkey程序在模拟器或设备运行的时候, ...

随机推荐

  1. [bzoj4893]项链分赃

    来自FallDream的博客,未经允许,请勿转载,谢谢. 有一串长度为n(n<=10^5)的项链,上面有红绿蓝三种颜色的珠子,每种颜色的珠子数目都是偶数,现在要你把它切几刀分成若干段,把其中一些 ...

  2. 百度杯CTF夺旗大赛9月场writeup

    在i春秋上注册了账号,准备业余时间玩玩CTF.其中的九月场已经打完了,但是不妨碍我去做做题,现在将一些思路分享一下. 一. 第二场web SQL 根据题目来看是一个SQL注入的题目: 这里推荐两篇文章 ...

  3. Android Activity的任务栈和四大启动模式

    在安卓系统中默认每次启动一个Activity时,系统会创建一个实例,并按照先进后出的原则放入任务栈中,当我们按back键时,就会有一个activity从任务栈顶移除,重复下去,直到任务栈为空,系统就会 ...

  4. Python之作业购物车

    作业之购物车优化 购物车优化要求如下: 用户入口: 启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表 允许用户根据商品编号购买商品 用户选择商品后,检测余额是否够,够就 ...

  5. ZH奶酪:Ionic中(弹出式窗口)的$ionicModal使用方法

    Ionic中[弹出式窗口]有两种(如下图所示),$ionicModal和$ionicPopup; $ionicModal是完整的页面: $ionicPopup是(Dialog)对话框样式的,直接用Ja ...

  6. 46. Permutations(medium, backtrack, 重要)

    Given a collection of distinct numbers, return all possible permutations. For example, [1,2,3] have ...

  7. 0. 迷之 -> 和 .

    0. 迷之 -> 和 . 箭头(->):左边必须为指针: 点号(.):左边必须为实体. e.g.1 class class A{ public: play(); }; int main() ...

  8. Docker学习系列(一)Docker简介

    简介 Docker是一个在全球范围领先的软件容器平台.开发人员可以使用容器来在协作过程中遇到的解决"不同环境配置"的问题.(例如,在传统的开发环境下,开发人员编写代码,然后交由测试 ...

  9. TP中的AJAX返回ajaxReturn()

    系统支持任何的AJAX类库,Action类提供了ajaxReturn方法用于AJAX调用后返回数据给客户端.并且支持JSON.XML和EVAL三种方式给客户端接受数据,通过配置DEFAULT_AJAX ...

  10. popen() 使用举例 (转载)

    函数原型: #include "stdio.h" FILE *popen( const char* command, const char* mode ) 参数说明: comman ...