文章出处:可不可以不取名(转载文章,如有不妥,通知后我会立即删除)
1 ANCS综述
ANCS即 Apple Notification Center Service。是IOS系统中的一个通知服务。设备连接手机后,设备首先需要先使能IOS系统的通知功能,具体即设备上的GATT 客户端发现IOS上的ANCS,并且使能其 通知源Characteristics 的notify功能。 之后IOS系统就会通过ble 推送消息给设备了。
通常推送的消息仅仅是一个简短通知,比如通知有一个社交消息。如果需要获取详细消息,还需要 设备通过 控制点 Characteristics 主动发送控制指令给 ANCS服务,让其返回详细信息。返回的详细信息通过一个数据源Characteristics来返回。所以连接上服务后除了使能通知源Characteristics的notify功能,还需要使能 数据源Characteristics的notify功能,因为可能需要通过数据源来获取通知的详细信息。
如下图所示:NC(通知消费者)连接NP(通知提供者)上后发现服务,然后 订阅(使能通知功能) 通知源和数据源,之后如果NP有消息就会 通过 通知源 通知NC了。
综上,ANCS是一个服务,
其服务UUID是特定的为7905F431-B5CE-4E99-A40F-4B1E122D00D0
该服务会主动推送一些 通知消息给 设备,所以有一个具有notify功能的Characteristics。
该特性称为Notification Source.
(注意这里 notify指的是Characteristics的发送消息方式, 而notification source仅仅是一个称谓,就是字面意思,表示这个Characteristics的目的是为了推送一些通知,所以称为通知源)
通过notification source发送过来的通知仅仅是简短的消息。如果希望获取更消息的消息则需要 设备主动发送控制指令给手机上的ANCS,所以该服务还有一个具有写功能的Characteristics,这样就可以通过这个Characteristics来发送控制指令给ANCS服务。这个特性称为Control Point
发送控制消息后 ANCS服务会返回更详细的消息。这个消息不会再通过notification source这个Characteristics,而是用过另一个具有 notify功能的Characteristics来返回,该特性称为Data Source。
综上ANCS服务至少有3个特性。其UUID如下:
· Notification Source: UUID 9FBF120D-6301-42D9-8C58-25E699A21DBD (notifiable)
· Control Point: UUID 69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9 (writeable with response)
· Data Source: UUID 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB (notifiable)
即 :notify source 这个Characteristics 是NP用来发送通知给NC的,
Control point这个Characteristics 是NC用来发送控制命令给NP的,如获取通知详细信息。
Data source这个Characteristics 是NP收到NC获取详细信息命令后返回通知的详细信息
下面分别介绍三个Characteristics 中(也可以认为是三个数据通道)传输的数据的 内容和格式
2 notify source :通知源
NP发送通知给NC的通道。其上发送的数据格式如下:
2.1 EventID:
表示这个通知是 added, modified, removed 三种中的哪种。
如果手机收到一个qq消息,则手机(NP)发给一个 added的通知给 设备( NC )。
如果用户在手机通知栏上滑动清除了这通知,则手机(NP)就会发送一个removed的通知给设备(NC)
Modified类型的具体还没碰到
2.2 EventFlags:
每个位有特殊的意义,用来指示这个通知的一些特性
EventFlagSilent | = (1 << 1), |
EventFlagPreExisting | = (1 << 3), |
EventFlagNegativeAction | Reserved= (1 << 5)–(1 << 7) |
2.2.1 Slient标记:
没搞清干吗用的。
2.2.2 Important标记:
表示通知重要,比如手机有来电时,推送给NC的通知其flag的important就会被置位,表示通知重要。
2.2.3 PreExisting标记:
表示消息是之前就存在,比如手机连接设备后,再断开设备,然后重新连接,则连接上后手机(NP)会发送一些 断开前就有的没处理的手机上的通知,这些通知的preExisting位就会被置位。
2.2.4 PositiveAction,NegativeAction标记:
称积极动作和消极动作吧,和每个具体通知有关, 比如手机收到 来电,则就会发送 来电通知给 设备,这个通知就通知具有这两个 标记,积极动作表示 接电话,而消极动作表示拒接电话。
再如,手机收到qq消息,则手机发送 通知给 设备,这个通知就只有 negativeaction标记。
PositiveAction,NegativeAction 这两个标记仅仅表示 这个”通知”具有一些预定义的动作,比如 电话通知的 接听和 拒接。 具体是否执行,则需要 通过控制通道发送 控制指令 执行 积极动作或者消极动作。
也就是 这两个标记仅仅表示 这个通知具有某个预定义的对这个通知的特殊处理,至于执不执行则要看 设备(NC) 是否发送执行PositiveAction 或NegativeAction的命令 后面 对控制通道的描述会有说明。
2.3 CategoryID:
用来分类通知类型的
CategoryIDOther | = 1, |
CategoryIDMissedCall | = 3, |
CategoryIDSocial | = 5, |
CategoryIDEmail | = 7, |
CategoryIDHealthAndFitness | = 9, |
CategoryIDLocation | = 11, |
CategoryIDvalues | = 0, |
NotificationAttributeIDTitle | = 2, (Needs to be followed by a 2-bytes max length parameter) |
NotificationAttributeIDMessage | = 4, |
NotificationAttributeIDDate | = 6, |
NotificationAttributeIDNegativeActionLabel | Reserved = 8–255 |
AppIdentifier该attribute表示发送这个通知App的标识。比qq消息的app id就是com.tencent.mqq
Title 该attribute表示通知的标题,qq消息的标题就是QQ
Subtitle为子标题,通常为空。Message就是信息内容,MessageSize为信息大小,
Date为通知发出的时间(不是返回详细信息的时间,是 之前通知的发出时间),
PositiveActionLabel和NegativeActionLabel即描述 积极动作和消极动作具体是什么。 来电通知其积极动作和消极动作通常就是 接听和拒接。
具体过程如, 当手机qq收到一条qq消息时, 手机就会在 通知源通道上 推送一条 Social类型的通知给 设备,设备收到后 可以在 控制点通道上发送一条获取该通知详细命令,之后手机再通过 数据源通道返回其详细信息。
3.1 获取通知的详细信息的命令格式和 响应数据格式
既然通知的详细信息是由一个个 attribute组成,那么我们获取详细信息的时候就可以自己指定 获取 这个 通知的 哪些attribute。所以获取通知详细命令的格式如下:
3.1.1 CommandID:
获取通知详细信息的 命令ID为0
3.1.2 NotificationUID:
用来具体标识要获取哪个通知的详细消息,这个值就是用 通知源通道中收到的通知的NotificationUID字段。
3.1.3 AttributeID n:
这些字段即指定想获取这个通知的哪些详细信息,一些attributeID之后需要跟2字节的max length表示 设备(NC)期望获取这个通知该特性信息的最大长度。具体哪些attribute需要跟2字节max length在前面的attributes表中有说明。
获取通知attributes(即获取通知详细信息)在 控制点通道上发出以后,NP(手机)就会在 数据源通道返回这些 attributes的值。即通知的一些具体信息。返回的响应数据格式如下:
CommandID同样还是0,表示该响应是获取通知attributes的响应,
NotificationUID 与 命令中的NotificationUID对应,用来表示返回的这些attributes的值是 对应哪个 通知的。
随后就是 具体的attributes的值了, 均由3字段组成,分别表示attribute,其值长度,具体值。
3 . 2 获取手机上产生本条通知的APP的信息
如何获取 产生这个通知的app的消息? 设备收到的通知实际是 手机发送过来的,而手机之所以发送这个通知给设备时因为 手机中的一些应用产生了一些消息。
比如,手机上的qq产生了一条消息,则手机通知栏上就会产生这个通知,同时也会推送一条 Social类型的通知给 连接的设备。
所以 设备端 想获取 产生这个通知的APP的一些信息,首先应该 获取 该通知由哪个app产生的,然后才能查询该app的消息。
前面提到,收到通知后,一般需要再 在控制通道上发送获取通信详细信息的命令来获取到 该通知相关的一些更具体的信息, 而获取详细信息实际就是获取这个通知的 一些 attributes 的具体的值。
其中就有一个 attribute用来标识 是由哪个 app 产生的这个通知,即NotificationAttributeIDAppIdentifier。
所以受到通知后首先 需要使用 获取通知attributes的命令来获取其NotificationAttributeIDAppIdentifier的具体值,这个就知道了产生这个 通知的app的标识。
之后再通过 获取 app信息命令来获取 产生这个通知的app的信息,命令格式如下
CommandID:为1,标识获取 app的相关信息命令。
App Identifier: 用来指示获取哪个app信息。就是获取通知详细信息中返回的NotificationAttributeIDAppIdentifier的值。
Attributes: 获取通知的详细信息 就是获取通知一些attributes的值,同样获取APP详细信息 也就是 获取 APP的一些attributes。
目前:app相关的 attributes只有一个,即其名字。
AppAttributeIDDisplayName | Reserved = 1–255 |
同样 获取 app详细信息的返回也是通过 数据源通道返回。
CommandID:为1,标识获取 app的相关信息命令的响应。
App Identifier: 与命令中的app id对应,用来指示获取哪个app信息。
随后就是具体的各个 attributes的值。
如下图是 收到qq消息的通知后,获取其详细信息,并通过 app id这个attribute来获取 app的消息
3.3 执行通知预定义动作
通知源部分有 提到一些通知具有一些预定义的执行动作,通过 通知的EventFlags 字段来指示这个通知是否 有预定义的 积极动作或消极动作。来电通知就有 接听/拒听的 积极动作/消极动作。
所以如果收到 来电通知时, 即 通知CategoryID字段为CategoryIDIncomingCall 时,如果接听,就可以让设备 在控制点 通道上发送 执行积极动作的命令, 同理如果拒接,就在 控制点通道 上发送执行消极动作的命令。
执行预定义命令格式如下