极光推送的设备唯一性标识 RegistrationID

极光推送的设备唯一性标识 RegistrationID | 极光博客 https://blog.jiguang.cn/registrationid/

非常重要的。否则,每次用户在设备上卸载掉应用再重新安装,后端系统只能把这个用户当作一个全新的用户了。

Android 上识别设备的唯一性,因为这个圈太乱,所以设备本身的任何标识都是无法直接用作设备唯一标识的。iOS 是系统强力限制被唯一识别的,目前唯一可以部分满足条件是 IDFA,但需要你的 App 本身的确嵌入了广告。

很多开发者使用极光推送时,都有这个疑问:极光推送是如何来做设备的唯一性识别的。本文解析极光推送如何尽可能地来唯一识别设备。

极光推送对安装在设备上的 App 使用 RegistrationID 作为标识。极光推送要『尽可能』确保设备的唯一性,就是要使得 RegistrationID 尽可能唯一。

RegistrationID 的定义

关于 RegistrationID 极光官方文档有如下的定义:

集成了 JPush SDK 的应用程序在第一次 App 启动后,成功注册到 JPush 服务器时,JPush 服务器会给客户端返回唯一的该设备的标识 - RegistrationID。JPush SDK 会以广播的形式发送 RegistrationID 到应用程序。

有了这个标识,App 编程可以把这个 RegistrationID 保存到自己的应用服务器上,然后就可以根据 RegistrationID 来向设备推送消息或者通知。

RegistrationID 变化可能性

如果 App 不卸载,是直接覆盖安装,Android, iOS 上 RegistrationID 的值都不会变化。

如果 App 是卸载之后再次安装:

  • Android 上 RegistrationID 基本不会变;

  • iOS 上如果启用了 IDFA 变化可能性不大,如果未启用 IDFA 则每次安装 RegistrationID 都会变;

RegistrationID 生成规则解析

Android 平台

Android 上因为国内存在大量山寨设备的原因,正常的 IMEI, Mac Address, AndroidID 这些可以考虑用作唯一标识的值,都是不可以用的,因为这些值在一批设备中可能都是同一个值。

极光的基本思路是:

  1. 生成一个 DeviceID 保存到 Settings, External Storage。依赖本地存储,应用被卸载后重新安装这些存储里的 DeviceID 还在的话,就是同一个设备。这一条理论上解决 90% 的不变性问题。

  2. DeviceID 之外增加补充规则:综合根据 IMEI, MAC Address, AndroidID 这几个值来判断,是否可能是老设备。

具体的逻辑细节,也是根据实际运行情况,以及收集到的反馈不断调整的,大多数逻辑可在服务器端调整。

iOS平台

鉴于 iOS 系统设计上限制设备唯一标识,所以极光一直使用 Device Token 作为标识,也因为极光推送本身就是需要 Device Token 这个值才可能运作的。

iOS 9 版本之后,每次卸载后重装都会导致 Device Token 变化,所以对于极光后台来说,都只能被识别为新用户。

极光 SDK 新版本增加了 IDFA 选项,在集成初始化 SDK 时可选把 IDFA 这个值设置进来,这样极光后台就优先根据 IDFA 值来识别用户,从有一定的可能性应用被卸载后重装还能识别回老设备。

IDFA 是广告标识符,是 iOS 专门为广告跟踪唯一地识别用户而设计的。在 iOS 设备上,设备 -> 隐私 -> 广告这个页面,有一个设置项:限制广告跟踪。默认是未选中状态的,即是关闭状态,是不限制的。用户可以选中,从而限制广告跟踪。设置项之外还有一个按钮:还原广告标识符…。如果用户点击了这个按钮,则 IDFA 值会变化。

默认的情况下,没有限制广告跟踪,可以取到 IDFA 这个值。并且用户未点击『还原广告标识』时,这个值是不会变的。这样就达到了唯一地标识设备、跟踪到用户的目标。

但是,但是,请一定留意,IDFA 并不是一定可以启用的,是需要你的 App 的确有广告功能才可以用的,否则 Apple 在上架审核时有可能发现从而拒绝上架。

关于苹果 App 上架对 IDFA 的要求,可参考这里的说明:The Advertising Identifier (IDFA)

高级使用建议

因为 RegistrationID 是 JPush SDK 注册完成之后才得到的,所以调用 SDK API 来获取 RegistrationID 的值时需要稍注意,不是总能够立即得到。

比如 iOS 上建议在监听到 kJPFNetworkDidLoginNotification 这个通知后的代码里,来获取 RegistrationID 的值。

Coroutines declared with async/await syntax is the preferred way of writing asyncio applications. For example, the following snippet of code (requires Python 3.7+) prints “hello”, waits 1 second, and的更多相关文章

  1. Python PEP 492 中文翻译——协程与async/await语法

    原文标题:PEP 0492 -- Coroutines with async and await syntax 原文链接:https://www.python.org/dev/peps/pep-049 ...

  2. 用 Python 3 的 async / await 做异步编程

    前年我曾写过一篇<初探 Python 3 的异步 IO 编程>,当时只是初步接触了一下 yield from 语法和 asyncio 标准库.前些日子我在 V2EX 看到一篇<为什么 ...

  3. Async/Await FAQ

    From time to time, I receive questions from developers which highlight either a need for more inform ...

  4. [转] Understanding JavaScript’s async await

    PS:Promise的用处是异步调用,这个对象使用的时候,call then函数,传一个处理函数进去,处理异步调用后的结果 Promise<Action>这样的对象呢,异步调用后的结果是一 ...

  5. JavaScript基础——深入学习async/await

    本文由云+社区发表 本篇文章,小编将和大家一起学习异步编程的未来--async/await,它会打破你对上篇文章Promise的认知,竟然异步代码还能这么写! 但是别太得意,你需要深入理解Promis ...

  6. C++ std::async vs async/await in C# - Stack Overflow

    C++ std::async vs async/await in C# - Stack Overflow 我想知道新的c ++功能std::async是否与两个C#关键字async / await相当 ...

  7. [翻译] Python 3.5中async/await的工作机制

    Python 3.5中async/await的工作机制 多处翻译出于自己理解,如有疑惑请参考原文 原文链接 身为Python核心开发组的成员,我对于这门语言的各种细节充满好奇.尽管我很清楚自己不可能对 ...

  8. 【转】6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)

    原文:https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec105 ...

  9. 【C# TAP 异步编程】三、async\await的运作机理详解

    [原创] 本文只是个人笔记,很多错误,欢迎指出. 环境:vs2022  .net6.0 C#10 参考:https://blog.csdn.net/brook_shi/article/details/ ...

随机推荐

  1. iOS如何在应用中添加图标更换功能

    一.在info.plist中设置图标信息 首先将需要更换的图标按照下面的方式声明,以便我们能够正常调用文件和方法.注意,每个图标的图标名称和对应的文件名要一一对应. 二.在工程根目录下添加图标文件 图 ...

  2. Docker入门 - 004 Docker 容器使用

    Docker 客户端 docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项. docker 可以通过命令 docker command -- ...

  3. Rabbit五种消息队列学习(二) – 简单队列

    队列结构图 P:消息的生产者 C:消息的消费者 红色:队列 生产者将消息发送到队列,消费者从队列中获取消息. 测试 1.连接MQ public static Connection getConnect ...

  4. Android 网络编程之最新OKHTTP:3.9.0

    本节前言 本来是想围绕着HttpClient讲解的,后来发先Android4.4之后okhttp代替了hc,所以将不再讲解hc okhttp的简单使用,主要包含: 一般的get请求 一般的post请求 ...

  5. linux内核剖析(六)Linux系统调用详解(实现机制分析)

    本文介绍了系统调用的一些实现细节.首先分析了系统调用的意义,它们与库函数和应用程序接口(API)有怎样的关系.然后,我们考察了Linux内核如何实现系统调用,以及执行系统调用的连锁反应:陷入内核,传递 ...

  6. maven scope使用和理解

    在Maven的依赖管理中,经常会用到依赖的scope设置.这里整理下各种scope的使用场景和说明,以及在使用中的实践心得. scope的使用场景和说明 1.compile 编译范围,默认scope, ...

  7. Effective Java 第三版——71. 避免不必要地使用检查异常

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  8. MyBatis3 入门学习指南

    官网原文:http://www.mybatis.org/mybatis-3/zh/index.html 1.简介 1.1 什么是 MyBatis? MyBatis 是一款优秀的持久层框架,它支持定制化 ...

  9. [Linux]linux下取消用户名和密码直接登录

    假定目前只有root用户,则有如下两种方式可直接登录系统: 方式一: 1. passwd -d root 2. 修改/lib/systemd/system/serial-getty\@.service ...

  10. Deepin 系统下安装VMware并激活

    1.打开深度商店:搜索VMware,并下载安装. 2.打开启动器:点击VMware-install. 3.填写管理员密码. 4.下一步,完成安装. 5.打开VMware Workstation,输入密 ...