#####導語
智慧BLE硬體裝置需要實時獲取Android和iOS端通知,那他們分別是怎麼實現的呢?
#####一,探討Android &iOS 區別
- Android端手機是通過NotificationListenerService服務來獲取通知欄上的資訊,當然這個服務需要獲取到對應的許可權.通過服務獲取到的具體訊息,然後通過BLE或者傳統藍芽傳輸到智慧硬體端.然後智慧硬體顯示該訊息
- iOS 端手機是通過ANCS服務來獲取對應訊息,該服務在開機後就啟動啦,只等訂閱裝置來訂閱。智慧硬體端訂閱ANCS服務成功後,一旦有新訊息,比如來電或者其它App推送訊息,蘋果通知中心NotificationCenter就推送一份到訂閱裝置上,同時往通知中心上推送一份。 總結如下結論: iOS端手錶或手環裝置獲取到訊息幾乎是同時的。速度較快 Android裝置需要繼承通過對應的服務,然後在通過自己的傳輸協議傳到手錶或手環端,速度上較iOS慢點。
#####二, 初見ANCS ANCS(Apple Notification Center Service)意思是蘋果通知中心服務,它是蘋果提供給周邊藍芽裝置(手環、手錶等智慧裝置)通過BLE(低功耗藍芽)訪問iOS裝置上的各類通知的一種機制. ANCS協議中的通用屬性協議(Generic Attribute Profile,GATT)協議實現的,它是GATT協議的一個子集。 在ANCS協議中,iOS裝置作為server端,既資料提供者NP(Notification Provider),充當Peripheral端的角色. 周邊裝置如智慧手錶或者手環作為client端即資料消費者Notification Consumer (NC),充當Central,主要是用來連線和使用ANCS server提供的服務,如何從服務中獲取對應的資訊。 ANCS作為Perpheral暴露給外界裝置的服務UUID是7905F431-B5CE-4E99-A40F-4B1E122D00D0,所以通過該service就能獲取到對應的特徵值,然後獲取特徵值裡面的內容。 ANCS給我們提供了下面3種特徵值(Characteristic)
- Notification Source: UUID 9FBF120D-6301-42D9-8C58-25E699A21DBD(notifiable) 基本通知源,通知一些計數的資訊,可以通過notification 獲取uuid,
- Control Point: UUID 69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9(writeablewithresponse) 控制器,用於向ios裝置寫入控制資訊,例如讀取詳情 ,接聽來電,拒絕來電等
- Data Source: UUID 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB(notifiable) 資料來源,用於提供詳細資料,在控制資訊寫入後通過此characteristic返回
所以智慧BLE裝置需要訂閱Notification Source 和 Control Point 來獲取DataSource資料來源資訊,下面對上面Characteristic特徵值進行詳細解釋.
1)Notification Source
- EventID Values 如下Table
| EventID Values | 值 | 代表含義| | ------------- |:-------------:| | EventIDNotificationAdded | =0 | 訊息是新來的| | EventIDNotificationModified | =1 |訊息是修改的 | | EventIDNotificationRemoved | =2 |移除訊息 | | Reserved EventID values | = 3–255 | 其它|
- EventFlags如下Table
EventFlags Values | 值 |
---|---|
EventFlagSilent | = (1 << 0) |
EventFlagImportant | = (1 << 1) |
EventFlagPreExisting | = (1 << 2) |
EventFlagPositiveAction | = (1 << 3) |
EventFlagNegativeAction | = (1 << 4) |
Reserved EventFlags | = (= (1 << 5)–(1 << 7)) |
- CategoryID 代表該訊息的型別
CategoryID Values | 值 | 代表含義 |
---|---|---|
CategoryIDOther | = 0 | 其他類別 |
CategoryIDIncomingCall | = 1) | 來電訊息 |
CategoryIDMissedCall | = 2 | miss電話訊息 |
CategoryIDVoicemail | = 3 | voice mail訊息 |
CategoryIDSocial | = 4 | 社交類訊息 比如微信facebook等 |
CategoryIDSchedule | =5 | schedule訊息 |
CategoryIDEmail | =6 | Email訊息 |
CategoryIDNews | =7 | News訊息 |
CategoryIDHealthAndFitness | =8 | 健康類訊息 |
CategoryIDBusinessAndFinance | =9 | 財經類訊息 |
CategoryIDLocation | =10 | location訊息 |
CategoryIDEntertainment | =11 | 娛樂類訊息 |
Reserved CategoryID values | = 12–255 | 其他類訊息 |
-
CategoryCount:給定型別中活躍的通知的數量。例如,郵箱中有兩封未讀的郵件,這個時候又來了一封新的郵件,那麼通知的郵件的數量將是3
-
NotificationUID: 32byte 唯一標示該訊息.後續Control Point需要用這個NotificationUID,可以獲取到具體的資訊datasource.
比如下面訊息就是獲取到一個
2)Control Point NC裝置需要更多資訊,這個時候可以用Control Point獲取通知屬性命令使得NC可以得到某個特定通知的詳細屬性,比如簡訊的傳送人,簡訊內容,時間,App name 等。
- CommandID: 設為零 (CommandIDGetNotificationAttributes),0x00
- NotificationUID: 想要獲得的通知的uid,32位數字是通知的唯一標示。
- AttributeIDs:NC想要獲得的屬性列表。有些屬性可能需要後面接一個16位的的引數,0xff 0xff。
想要獲取具體某條資訊可以通過下面的方法
public static byte[] getNotificationByUID(byte[] uid){
byte appNameCapacity=100;//app name 最長容量
byte titleCapacity=50;//title 最長
byte subtitleCapactiy=100;//subtitle
byte msgCapacity=248;//msg最大容量
byte size=10;
byte dateCapacity=10;
ByteArrayOutputStream bout=new ByteArrayOutputStream();
bout.write(0);//注意此處是commonID 一般情況是0
bout.write(uid),//把notification uid 傳過來
bout.write(1);
bout.write(titleCapacity);
bout.write(0);
bout.write(2);
bout.write(subtitleCapactiy);
bout.write(0);
bout.write(3);
bout.write(msgCapacity);
bout.write(0);
bout.write(4);
bout.write(size);
bout.write(0);
bout.write(5);
bout.write(dateCapacity);
bout.write(0);
bout.write(0);
bout.write(appNameCapacity);
byte[] req=bout.toByteArray();
bout.reset();
return req;
}
複製程式碼
通過Control Point 傳輸上面的byte 流給iOS NSNotification center,iOS會根據傳輸過來的byte流,傳回具體資訊到裝置訂閱端,裝置通過回撥函式解析傳過來的byte流。下面獲取到byte流如下:
通過上面的byte資料結構可以寫出對應的parse函式。獲取具體的資料。通過1Byte AttritbuteID 知道是具體哪個NotificationAttributeID Values,2個byte AttributeLength 知道後面data有幾位byte ,byte 資料 緊跟在AttributeLength後面.
NotificationAttributeID Values
NotificationAttributeIDAppIdentifier Values | 值 | 代表含義 |
---|---|---|
NotificationAttributeIDAppIdentifier | = 0 | 其他類別 |
NotificationAttributeIDTitle | =1 | 表示title |
NotificationAttributeIDSubtitle | =2 | subtitle |
NotificationAttributeIDMessage | =3 | 具體Message |
NotificationAttributeIDMessageSize | =4 | 具體Message大小 |
NotificationAttributeIDDate | =5 | 具體date |
NotificationAttributeIDPositiveActionLabel | =6 | |
NotificationAttributeIDNegativeActionLabel | =7 | |
Reserved NotificationAttributeID values | =8-255 |
Note NotificationAttributeIDDate 獲取對應的資料格式是yyyyMMdd'T'HHmmSS,所以獲取到對應的Date,要用這種格式來解析.
3)整體NP和NC交換流程
4)Notification Actions 從iOS8開始,NP傳送的iOS通知起始可以間接的告訴NC可執行哪些動作。接著,NC就可以針對指定的iOS通知,請求NP執行一個動作。 通知源特徵上生成的GATT通知包含一個叫做Eventflags的資料域,NC根據這個資料域就可得知對一條iOS通知可以執行哪些操作:
EventFlagPositiveAction:積極動作(Positive Action),與iOS通知相關。 EventFlagNegativeAction:消極動作(Negative Action),與iOS通知相關。
比如iPhone來電啦,接聽來電可以用EventFlagPositiveAction action來 拒絕來電的時候用EventFlagNegativeAction action來. 通過下面程式碼就可以實現具體掛電話or接話等操作:
public static byte[] getActionCommend(byte[] uid,int actionId){
ByteArrayOutputStream out=new ByteArrayOutputStream();
out.write(2);
out.write(uid);
out.write(actionId);
byte [] req=out.toByteArray();
out.reset();
return req;
}
複製程式碼
ActionID Values :
ActionID Values | 值 |
---|---|
ActionIDPositive | =0 |
ActionIDNegative | =1 |
Reserved ActionID values | =2-255 |