Za pomocą prostych interfejsów API REST możesz wstawiać, aktualizować, odczytywać i usuwać karty statyczne. Dodatkowo możesz dołączać obiekty do karty statycznej, na przykład lokalizacji lub multimediów.
Działanie
Karty statyczne znajdują się domyślnie po prawej stronie zegara Glass i zawierają informacje istotne dla użytkownika w momencie dostawy. Nie wymagają one natychmiastowej uwagi, tak jak karty na żywo. Użytkownicy mogą czytać kartę lub korzystać z niej w dogodnym dla siebie czasie.
Gdy Glassware wkłada karty statyczne do osi czasu, urządzenie może odtwarzać dźwięk powiadomienia, aby ostrzec użytkowników. Wszystkie poprzednie karty statyczne również zmieniają się w prawo i znikają z osi czasu po 7 dniach lub po upływie 200 kart.
Kiedy ich używać
Karty statyczne świetnie nadają się do wysyłania użytkownikom powiadomień okresowych.
Na przykład usługi związane z dostarczaniem najnowszych wiadomości. Karty statyczne interfejsu API lustrzanych mogą też uruchamiać aktywne karty lub zanurzenie w menu OPEN_URI
. Pozwala to tworzyć interakcje hybrydowe, które wykorzystują karty statyczne jako powiadomienia, oraz kartę na żywo lub immersję, aby zwiększyć interaktywność.
Pełną listę możliwych operacji na elementach osi czasu znajdziesz w dokumentacji.
Wkładanie kart statycznych
Aby wstawić karty statyczne (elementy na osi czasu), POST przedstaw element JSON na osi czasu w punkcie końcowym REST.
Większość pól w elemencie osi czasu jest opcjonalna. W najprostszej postaci element na osi czasu zawiera tylko krótki tekst, jak w tym przykładzie:
Nieprzetworzony protokół HTTP
POST /mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Content-Type: application/json
Content-Length: 26
{ "text": "Hello world" }
Java
TimelineItem timelineItem = new TimelineItem();
timelineItem.setText("Hello world");
service.timeline().insert(timelineItem).execute();
Python
timeline_item = {'text': 'Hello world'}
service.timeline().insert(body=timeline_item).execute()
Pomyślnie otrzymasz kod odpowiedzi 201 Created
z pełną kopią utworzonego elementu. W poprzednim przykładzie pomyślna odpowiedź może wyglądać tak:
Nieprzetworzony protokół HTTP
HTTP/1.1 201 Created
Date: Tue, 25 Sep 2012 23:30:11 GMT
Content-Type: application/json
Content-Length: 303
{
"kind": "glass#timelineItem",
"id": "1234567890",
"selfLink": "https://www.googleapis.com/mirror/v1/timeline/1234567890",
"created": "2012-09-25T23:28:43.192Z",
"updated": "2012-09-25T23:28:43.192Z",
"etag": "\"G5BI0RWvj-0jWdBrdWrPZV7xPKw/t25selcGS3uDEVT6FB09hAG-QQ\"",
"text": "Hello world"
}
Wstawiony element, który pojawi się na osi czasu użytkownika, będzie wyglądać tak:
Wstawianie elementu na osi czasu z załącznikiem
Obraz wart jest tysiąc słów, czyli więcej, niż mieści się na osi czasu. W tym celu możesz też dołączyć obrazy i filmy do elementu na osi czasu. Oto przykład wstawiania elementu osi czasu ze zdjęciem:
Nieprzetworzony protokół HTTP
POST /upload/mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Content-Type: multipart/related; boundary="mymultipartboundary"
Content-Length: {length}
--mymultipartboundary
Content-Type: application/json; charset=UTF-8
{ "text": "A solar eclipse of Saturn. Earth is also in this photo. Can you find it?" }
--mymultipartboundary
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
[binary image data]
--mymultipartboundary--
Java
TimelineItem timelineItem = new TimelineItem();
timelineItem.setText("Hello world");
InputStreamContent mediaContent = new InputStreamContent(contentType, attachment);
service.timeline().insert(timelineItem, mediaContent).execute();
Python
timeline_item = {'text': 'Hello world'}
media_body = MediaIoBaseUpload(
io.BytesIO(attachment), mimetype=content_type, resumable=True)
service.timeline().insert(body=timeline_item, media_body=media_body).execute()
Element na osi czasu z dołączonym obrazem wygląda mniej więcej tak:
Załączanie filmu
Jeśli załączasz pliki wideo do elementów na osi czasu, zalecamy przesłanie ich strumieniowo zamiast przesyłania całego ładunku naraz. Interfejs Google Mirror API obsługuje strumieniowe przesyłanie danych przez HTTP, pobieranie progresywne i protokół RTSP. Protokół RTSP jest często zablokowany przez zapory sieciowe, dlatego używaj w miarę możliwości innych opcji.
Aby odtwarzać strumieniowo film, użyj wbudowanej opcji PLAY_VIDEO
i określ adres URL filmu jako payload
. Więcej informacji znajdziesz w artykule na temat dodawania wbudowanych pozycji menu i obsługiwanych formatów multimediów.
Z podziałem na strony
Dzielisz na strony elementy na osi, które nie mieszczą się na jednej karcie osi czasu, ale powinny być powiązane z tą samą kartą. Podział elementów na strony dotyczy tego samego elementu timeline.id
i zapewnia taki sam zestaw elementów menu. Gdy użytkownik kliknie element podzielony na strony, pojawi się pozycja Więcej informacji.
Google Glass automatycznie dzieli na strony elementy na osi czasu, które wyświetlają text
. Aby umożliwić Google Glass automatyczne dzielenie treści na strony html
, użyj tagu article
z właściwością klasy ustawioną na auto-paginate
, jak w tym przykładzie:
<article class="auto-paginate">
<h3>Very long list</h3>
<ul>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
<li>Fourth item</li>
<li>Fifth item</li>
<li>Sixth item</li>
<li>...</li>
</ul>
<article>
W podziale na strony użyj tagu article
dla treści, które chcesz wyświetlać na poszczególnych kartach. Google Glass wyświetla zawartość każdego tagu article
na osobnej karcie osi czasu. Możesz na przykład utworzyć element podziału na strony z użyciem tego kodu HTML:
<article>
<section>
<p>First page</p>
</section>
</article>
<article>
<section>
<p>Second page</p>
</section>
</article>
<article>
<section>
<p>Third page</p>
</section>
</article>
Domyślnie pierwsza strona osi czasu podzielona na strony jest wyświetlana jako karta okładki i ponownie wyświetlana, gdy użytkownik wybierze opcję menu Więcej informacji. Aby zapobiec wyświetlaniu pierwszej karty po kliknięciu Więcej informacji, możesz określić klasę CSS cover-only
dla pierwszego tagu <article>
:
<article class="cover-only">
...
Klasa cover-only
obsługuje też automatycznie podzielone na strony elementy osi czasu:
<article class="auto-paginate cover-only">
...
Grupowanie
Grupowanie pozwala grupować powiązane, ale różniące się elementy, jak na przykład poszczególne wiadomości w wątku e-maila. Pakiety mają główną kartę okładki, którą użytkownik klika, aby wyświetlić oś czasu zawierającą inne karty w pakiecie. Pakiety różnią się od zwykłych kart na osi czasu od wierzchu w prawym górnym rogu karty okładki pakietu.
Aby połączyć elementy na osi czasu, utwórz je z taką samą wartością w bundleId
. Ostatni dodany element to karta okładki pakietu.
Poniższa ilustracja przedstawia kartę tytułową złożoną z rogów w prawym górnym rogu i dwie karty poniżej.
Odczytywanie elementów osi czasu
Twoja usługa ma dostęp do wszystkich utworzonych elementów osi czasu i wszystkich udostępnionych na niej elementów na osi czasu. Dowiedz się, jak wyświetlić listę osi czasu, które są widoczne dla usługi.
Nieprzetworzony protokół HTTP
GET /mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Java
TimelineItem timelineItem = new TimelineItem();
service.timeline().list().execute();
Python
service.timeline().list().execute()
Aby pobrać, zaktualizować i usunąć elementy osi czasu, możesz użyć innych operacji REST.
Dostęp do załączników
Załączniki do elementu na osi czasu możesz wyświetlić, korzystając z właściwości tablicy o nazwie attachments
.
Dane binarne można pobrać za pomocą właściwości contentUrl
załącznika lub punktu końcowego załączników.
Nieprzetworzony protokół HTTP
GET /mirror/v1/timeline/{itemId}/attachments/{attachmentId} HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Java
TimelineItem item = service.timeline().get(itemId).execute();
String attachmentId = item.getAttachments().get(0).getId();
service.attachments().get(itemId, attachmentId).executeAsInputStream();
Tworzę pozycje menu
Elementy menu pozwalają użytkownikom wykonywać działania związane z kartą osi czasu. Są 2 rodzaje elementów: wbudowane i niestandardowe menu.
Wbudowane pozycje menu umożliwiają korzystanie ze specjalnych funkcji usługi Glass, takich jak odczytywanie kart na osi czasu, nawigowanie do lokalizacji, udostępnianie obrazu czy odpowiadanie na wiadomości.
Niestandardowe pozycje menu umożliwiają aplikacji wyświetlanie informacji o swoim urządzeniu Glass, a także możesz dodać ikonę elementu menu, która pasuje do Twojej marki.
Dodawanie wbudowanych pozycji menu
Możesz dodać wbudowane elementy menu do osi czasu, wypełniając je menuItems array
.
Aby użyć wbudowanej pozycji menu, musisz wypełnić tylko właściwość action
każdego atrybutu menuItem
.
Nieprzetworzony protokół HTTP
HTTP/1.1 201 Created
Date: Tue, 25 Sep 2012 23:30:11 GMT
Content-Type: application/json
Content-Length: 303
{
"text": "Hello world",
"menuItems": [
{
"action": "REPLY"
}
]
}
Definiowanie niestandardowych pozycji menu
Jeśli wbudowane elementy menu nie sprawdzają się w Twoim przypadku, możesz utworzyć własne pozycje menu, wykonując przy tym własne działania, wykonując następujące czynności podczas wstawiania lub aktualizowania elementu na osi czasu:
- Określ
CUSTOM
dlamenuItem.action
. - Określ
menuItem.id
. Gdy użytkownik kliknie pozycję menu niestandardowego, urządzenie Glassware otrzyma powiadomienie z wartościąmenuItem.id
. Pozwala to określić źródło powiadomienia. - Określ
menuItem.values
, aby dodaćiconUrl
idisplayName
widoczne w Google Glass. Wskaż biały obraz o rozmiarze 50 x 50, w kolorze „iconUrl
” na przezroczystym tle. Określ
displayTime
. Jeśli nie określisz wartościdisplayTime
, element osi czasu zostanie przeniesiony na początek osi czasu za każdym razem, gdy użytkownik kliknie element menu niestandardowego.
Nieprzetworzony protokół HTTP
HTTP/1.1 201 Created
Date: Tue, 25 Sep 2012 23:30:11 GMT
Content-Type: application/json
Content-Length: 303
{
"text": "Hello world",
"displayTime": "2013-08-08T22:47:31-07:00",
"menuItems": [
{
"action": "CUSTOM",
"id": "complete"
"values": [{
"displayName": "Complete",
"iconUrl": "http://example.com/icons/complete.png"
}]
}
]
}
Umożliwianie użytkownikom przypinania karty osi czasu
Możesz utworzyć pozycję menu, która umożliwia użytkownikom przypinanie karty osi czasu, która zawsze wyświetla kartę osi czasu po lewej stronie głównej karty zegara. Użytkownicy mogą odpiąć kartę także za pomocą tego samego elementu menu.
Przypinana pozycja menu to wbudowany element menu, wystarczy więc, że podasz TOGGLE_PINNED
action
dla menuItem
.
Nieprzetworzony protokół HTTP
HTTP/1.1 201 Created
Date: Tue, 25 Sep 2012 23:30:11 GMT
Content-Type: application/json
Content-Length: 303
{
"text": "You can pin or unpin this card.",
"menuItems": [
{
"action": "TOGGLE_PINNED"
}
...
]
}
Subskrypcje
Interfejs Mirror API umożliwia subskrypcję powiadomień wysyłanych, gdy użytkownik wykona określone działania dotyczące Elementu osi czasu lub po zaktualizowaniu lokalizacji użytkownika. Gdy subskrybujesz powiadomienie, podajesz adres URL wywołania zwrotnego, który je przetwarza.
Odbieranie powiadomień
Powiadomienie z interfejsu Mirror API jest wysyłane jako żądanie POST
do subskrybowanego punktu końcowego zawierającego treść żądania JSON
.
Nieprzetworzony protokół HTTP
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "UPDATE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "<TYPE>",
"payload": "<PAYLOAD>"
}
]
}
Java
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.mirror.model.Notification;
import java.io.IOException;
import java.io.InputStream;
// ...
public class MyClass {
// ...
/**
* Parse a request body into a Notification object.
*
* @param requestBody The notification payload sent by the Mirror API.
* @return Parsed notification payload if successful, {@code null} otherwise.
*/
static Notification parseNotification(InputStream requestBody) {
try {
JsonFactory jsonFactory = new JacksonFactory();
return jsonFactory.fromInputStream(requetBody, Notification.class);
} catch (IOException e) {
System.out.println("An error occurred: " + e);
return null;
}
}
// ...
}
Python
import json
def parse_notification(request_body):
"""Parse a request body into a notification dict.
Params:
request_body: The notification payload sent by the Mirror API as a string.
Returns:
Dict representing the notification payload.
"""
return json.load(request_body)
Jeśli nie wystąpił błąd, usługa musi odpowiedzieć na interfejs API za pomocą kodu stanu HTTP 200 OK
.
Jeśli usługa zwróci kod błędu, interfejs Mirror API może spróbować ponownie wysłać powiadomienie do Twojej usługi.
Typy powiadomień
Interfejs Mirror API wysyła inny ładunek powiadomień dla różnych zdarzeń.
Odpowiedz
Użytkownik odpowiedział na Twoją oś czasu za pomocą wbudowanego elementu menu REPLY
:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "INSERT",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "REPLY"
}
]
}
Atrybut itemId
jest ustawiony na ID
elementu, który zawiera:
- Atrybut
inReplyTo
został ustawiony naID
elementu osi czasu, na który odpowiada. - Atrybut
text
został ustawiony na transkrypcję tekstu. - Atrybut
recipients
został ustawiony na wartośćcreator
elementu osi czasu, na który odpowiada (jeśli istnieje).
Przykład
{
"kind": "glass#timelineItem",
"id": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"inReplyTo": "3236e5b0-b282-4e00-9d7b-6b80e2f47f3d",
"text": "This is a text reply",
"recipients": [
{
"id": "CREATOR_ID",
"displayName": "CREATOR_DISPLAY_NAME",
"imageUrls": [
"CREATOR_IMAGE_URL"
]
}
]
}
Usuń
Użytkownik usunął element osi czasu:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "DELETE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "DELETE"
}
]
}
Wartość atrybutu itemId
jest ustawiona na identyfikator usuniętego elementu. Element nie zawiera już metadanych innych niż identyfikator i właściwość isDeleted
.
Wybrano pozycję menu niestandardowego
Użytkownik wybrał element menu niestandardowego ustawiony przez Twoją usługę:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "UPDATE",
"userToken": "harold_penguin",
"userActions": [
{
"type": "CUSTOM",
"payload": "PING"
}
]
}
Atrybut itemId
jest ustawiony na identyfikator elementu menu wybranego przez użytkownika.
Tablica userActions
zawiera listę działań niestandardowych wykonanych przez użytkownika na tym elemencie. Usługa powinna odpowiednio obsługiwać te działania.
Aktualizacja lokalizacji
Bieżący użytkownik ma dostęp do nowej lokalizacji:
{
"collection": "locations",
"itemId": "latest",
"operation": "UPDATE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer"
}
Gdy urządzenie Glassware otrzyma aktualizację lokalizacji, wyślij żądanie do punktu końcowego glass.locations.get, by pobrać najnowszą znaną lokalizację. Urządzenie Glassware otrzymuje aktualizacje lokalizacji co 10 minut.
Polecenie głosowe
Użytkownik aktywował polecenie głosowe, na przykład: „Ok Google, zanotuj, Cat Stream, Urodziny Chipotle'a mają jutro”. Do Glassware wysyłane jest to powiadomienie:
{
"collection": "timeline",
"operation": "INSERT",
"userToken": "chipotle's_owner",
"verifyToken": "mew mew mew",
"itemId": "<ITEM_ID>",
"userActions": [
{“type”: "LAUNCH"}
]
}
To powiadomienie różni się od innych powiadomień wartością LAUNCH
we właściwości userActions
.
Następnie możesz użyć wartości z pola itemId
, aby pobrać element osi czasu:
{
"id": "<ITEM_ID>",
"text": "Chipotle's birthday is tomorrow",
"recipients": [
{"id": "CAT_STREAM"}
]
}
Właściwość recipients
zawiera element id
kontaktu, który reprezentuje użyte polecenie głosowe.