Możesz wstawiać, aktualizować, odczytywać i usuwać karty statyczne za pomocą prostych interfejsów API typu REST. Do karty statycznej możesz dołączać obiekty, np. lokalizację lub nośnik.
Jak działają
Karty statyczne są domyślnie umieszczone po prawej stronie zegara Glass i wyświetlają informacje istotne dla użytkownika w momencie dostawy. Nie wymagają jednak natychmiastowej uwagi (np. kart transmisji na żywo), a użytkownicy mogą samodzielnie odczytać lub wykonać inne działania na karcie.
Gdy Glassware wstawia karty statyczne do osi czasu, może odtworzyć dźwięk powiadomienia, aby ostrzec użytkowników. Wszystkie wcześniejsze karty statyczne też przesuwają się w prawo i znikają z osi czasu po 7 dniach lub gdy jest ich 200 nowszych.
Kiedy ich używać
Karty statyczne idealnie nadają się do dostarczania okresowych powiadomień o ważnych wydarzeniach.
Może to być na przykład usługa dostarczania wiadomości, która na bieżąco przesyła najważniejsze wiadomości. Karty statyczne interfejsu Mirror API mogą też uruchamiać karty transmisji na żywo lub materiały informacyjne za pomocą pozycji menu OPEN_URI
. Dzięki temu możesz tworzyć interakcje hybrydowe, które wykorzystują karty statyczne jako powiadomienia oraz aktywne karty lub gry immersyjne, aby zapewnić bardziej interaktywną rozgrywkę.
Pełną listę możliwych operacji na elementach osi czasu znajdziesz w dokumentacji referencyjnej.
Wstawianie kart statycznych
Aby wstawić karty statyczne (elementy osi czasu), opublikuj reprezentację elementu osi czasu w formacie JSON w punkcie końcowym REST.
Większość pól elementu osi czasu jest opcjonalna. W najprostszej formie element na osi czasu zawiera tylko krótki komunikat tekstowy, jak w tym przykładzie:
Nieprzetworzony kod 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()
Jeśli wszystko się uda, otrzymasz kod odpowiedzi 201 Created
z pełną kopią utworzonego elementu. W poprzednim przykładzie pomyślna odpowiedź
może wyglądać tak:
Nieprzetworzony kod 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 jest wart tysiąca słów, a to znacznie więcej, niż można zmieścić na osi czasu. Do elementu osi czasu możesz też dołączać obrazy i filmy. Oto przykład wstawiania elementu osi czasu z załączonym zdjęciem:
Nieprzetworzony kod 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 osi czasu z załączonym obrazem wygląda na Google Glass podobny do tego:
Załączam film
Jeśli do elementów na osi czasu dołączasz pliki wideo, zalecamy przesyłanie strumieniowe filmu zamiast przesyłania całego ładunku za jednym razem. Interfejs Google Mirror API obsługuje strumieniowanie z użyciem transmisji na żywo przez HTTP, progresywnego pobierania oraz protokołu strumieniowego przesyłania w czasie rzeczywistym (RTSP). Protokół RTSP jest często blokowany przez zapory sieciowe, więc w miarę możliwości korzystaj z innych opcji.
Aby strumieniować wideo, użyj wbudowanego polecenia PLAY_VIDEO
i jako URL filmu podaj payload
tego elementu. Więcej informacji znajdziesz w sekcjach Dodawanie wbudowanych pozycji menu i obsługiwanych formatów multimediów.
Podział na strony
Możesz dzielić na strony elementy osi czasu, które nie mieszczą się na jednej karcie osi czasu, ale powinny być powiązane z tą samą kartą. Wszystkie pozycje podzielone na strony korzystają z tego samego elementu timeline.id
i dlatego mają ten sam zestaw pozycji menu. Gdy użytkownik kliknie element osi czasu podzielony na strony, pojawi się pozycja menu Więcej informacji.
Google Glass automatycznie dzieli elementy osi czasu na strony z wyświetlonym symbolem text
. Aby Google Glass automatycznie dzieliło strony 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>
Aby ręcznie podzielić treści 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. Na przykład możesz utworzyć element osi czasu podzielony na strony, używając 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 karta elementu osi czasu z podziałem na strony jest wyświetlana jako okładka i pojawia się ponownie, gdy użytkownik wybierze pozycję menu Więcej informacji. Aby uniemożliwić wyświetlanie 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ż elementy osi czasu podzielone automatycznie na strony:
<article class="auto-paginate cover-only">
...
Łączenie
Grupowanie pozwala na grupowanie powiązanych, ale odrębnych elementów, np. pojedynczych wiadomości w wątku e-maila. Pakiety mają główną okładkę pakietu, którą użytkownik może kliknąć, aby wyświetlić podoś czasu, która obejmuje inne karty z pakietu. Pakiety różnią się od zwykłych kart osi czasu dzięki zawinięciu narożnika w prawym górnym rogu okładki pakietu.
Aby połączyć elementy osi czasu, utwórz je z tą samą wartością bundleId
. Ostatnim dodanym elementem jest okładkę pakietu.
Poniższe obrazy przedstawiają pakiet ze zwijaną okładką w prawym górnym rogu, a pod nim 2 pakiety kart.
Odczytywanie elementów osi czasu
Usługa ma dostęp do wszystkich utworzonych przez siebie elementów osi czasu oraz do wszystkich elementów na osi czasu, które zostały jej udostępnione. Oto jak wyświetlić listę elementów osi czasu, które są widoczne dla Twojej usługi.
Nieprzetworzony kod 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()
Do pobierania, aktualizowania i usuwania elementów na osi czasu możesz używać innych operacji REST.
Dostęp do załączników
Dostęp do załączników do elementu osi czasu możesz uzyskiwać za pomocą właściwości tablicy o nazwie attachments
.
Dane binarne załącznika możesz wtedy pobrać za pomocą właściwości contentUrl
załącznika lub za pomocą punktu końcowego załączników.
Nieprzetworzony kod 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
Pozycje menu umożliwiają użytkownikom wysyłanie żądań działań związanych z kartą osi czasu. Są 2 rodzaje elementów menu: wbudowane i niestandardowe.
Wbudowane pozycje menu dają dostęp do specjalnych funkcji Google Glass, takich jak odczytywanie karty osi czasu, nawigowanie do lokalizacji, udostępnianie obrazu czy odpowiadanie na wiadomość:
Niestandardowe pozycje menu pozwalają aplikacji pokazać zachowanie charakterystyczne dla oprogramowania Glassware. Możesz też dodać ikonę menu, która pasuje do Twojej marki.
Dodawanie wbudowanych pozycji menu
Możesz dodać wbudowane pozycje menu do elementów na osi czasu, wypełniając pole menuItems array
podczas ich wstawiania.
Aby użyć wbudowanej pozycji menu, wystarczy, że wypełnisz action
każdego elementu menuItem
.
Nieprzetworzony kod 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 pozycje menu nie sprawdzają się w Twoim przypadku, możesz utworzyć niestandardowe pozycje menu z własnymi działaniami, wykonując te czynności podczas wstawiania lub aktualizowania elementu osi czasu:
- W polu
menuItem.action
podajCUSTOM
. - Określ wartość w polu
menuItem.id
. Gdy użytkownik dotknie tego menu, aplikacja Glassware otrzyma powiadomienie z wypełnioną wartościąmenuItem.id
. Dzięki temu możesz określić źródło powiadomienia. - Wpisz
menuItem.values
, aby dodaćiconUrl
idisplayName
, które będą widoczne na Google Glass. Wskaż obraz PNG o wymiarach 50 x 50, który jest biały z przezroczystym tłem dla elementuiconUrl
. Określ wartość w polu
displayTime
. Jeśli nie określisz wartościdisplayTime
, element osi czasu przesuwa się na początek osi czasu po kliknięciu tego elementu menu przez użytkownika.
Nieprzetworzony kod 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ć element menu umożliwiający użytkownikom przypięcie karty osi czasu, która na stałe wyświetla ją po lewej stronie głównej karty zegara. Użytkownicy mogą też odpiąć kartę za pomocą tego samego elementu menu.
Przypięcie pozycji menu jest wbudowaną funkcją, więc wystarczy, że podasz TOGGLE_PINNED
action
dla: menuItem
.
Nieprzetworzony kod 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 subskrybowanie powiadomień wysyłanych, gdy użytkownik wykona określone działania na elemencie osi czasu lub po zaktualizowaniu lokalizacji użytkownika. Gdy subskrybujesz powiadomienie, podajesz adres URL wywołania zwrotnego, który przetwarza powiadomienie.
Otrzymywanie powiadomień
Powiadomienie z interfejsu Mirror API jest wysyłane jako żądanie POST
do subskrybowanego punktu końcowego zawierającego treść żądania JSON
.
Nieprzetworzony kod 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, Twoja usługa musi odpowiedzieć na interfejs API kodem stanu HTTP 200 OK
.
Jeśli usługa w odpowiedzi wyświetli kod błędu, interfejs Mirror API może spróbować ponownie wysłać powiadomienie do usługi.
Typy powiadomień
Interfejs Mirror API wysyła inny ładunek powiadomień w przypadku różnych zdarzeń.
Odpowiedz
Użytkownik odpowiedział na element na osi czasu, używając 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 wartość ID
produktu zawierającego:
inReplyTo
ma wartośćID
elementu osi czasu, na który odpowiada.- Atrybut
text
został ustawiony na transkrypcję tekstu. - Atrybut
recipients
jest ustawiony nacreator
elementu osi czasu, na który jest odpowiedzią (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"
}
]
}
Atrybut itemId
przyjmuje identyfikator usuniętego elementu. Element nie zawiera już metadanych innych niż jego identyfikator i właściwość isDeleted
.
Wybrano niestandardową pozycję menu
Użytkownik wybrał niestandardową pozycję menu ustawioną 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 pozycji menu wybranej przez użytkownika.
Tablica userActions
zawiera listę niestandardowych działań, które użytkownik podjął w odniesieniu do danego elementu. Usługa powinna odpowiednio wykonać te działania.
Aktualizacja lokalizacji
Dla bieżącego użytkownika dostępna jest nowa lokalizacja:
{
"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, aby pobrać ostatnią znaną lokalizację. Twoje urządzenie Glassware otrzymuje aktualizacje lokalizacji co 10 minut.
Polecenie głosowe
Użytkownik aktywował polecenie głosowe, na przykład: „OK Glass, zanotuj, Cat Stream, urodziny Chipotle'a są jutro”. Na urządzenie Glass zostanie wysłane następujące 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 w polu itemId
do pobrania elementu 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.