Puoi inserire, aggiornare, leggere ed eliminare schede statiche utilizzando API REST semplici. Inoltre, puoi collegare gli oggetti a una scheda statica, ad esempio una posizione o i contenuti multimediali.
Funzionamento
Le schede statiche si trovano a destra dell'orologio di vetro per impostazione predefinita e mostrano informazioni pertinenti all'utente al momento della consegna. Tuttavia, non richiedono attenzione immediata come le schede pubblicate e gli utenti possono scegliere di leggere o utilizzare la scheda quando preferiscono.
Quando Glassware inserisce schede statiche nella sequenza temporale, Glass potrebbe riprodurre un suono di notifica per avvisare gli utenti. Anche tutte le schede statiche precedenti si spostano a destra e scompaiono dalla sequenza temporale dopo 7 giorni o quando le 200 schede sono più recenti.
Quando utilizzarli
Le schede statiche sono ottime per inviare
notifiche periodiche
agli utenti quando si verificano eventi importanti.
Ad esempio, un servizio di distribuzione delle notizie che invia le notizie principali non appena si verificano. Le schede statiche dell'API Mirroring
possono anche avviare schede pubblicate o
coinvolgimento tramite la voce di menu
OPEN_URI
. In questo modo puoi creare interazioni ibride che utilizzano le schede statiche come notifiche e una scheda in tempo reale o un'interazione per un'esperienza più interattiva.
Per un elenco completo delle possibili operazioni per gli elementi della sequenza temporale, consulta la documentazione di riferimento.
Inserimento di schede statiche
Per inserire le schede statiche (elementi della sequenza temporale), POSTA una rappresentazione JSON di un elemento della sequenza temporale nell'endpoint REST.
La maggior parte dei campi di un elemento nella sequenza temporale è facoltativa. Nella sua forma più semplice, un elemento della sequenza temporale contiene solo un breve SMS, come nell'esempio seguente:
HTTP non elaborato
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()
Se l'operazione è andata a buon fine, riceverai un codice di risposta 201 Created
con una copia completa dell'elemento creato. Nell'esempio precedente, una risposta corretta potrebbe avere il seguente aspetto:
HTTP non elaborato
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"
}
L'elemento inserito che appare nella sequenza temporale dell'utente ha il seguente aspetto:
Inserire un elemento della sequenza temporale con un allegato
Un'immagine vale mille parole, molto di più di quelle che puoi inserire in un elemento della sequenza temporale. A questo scopo, puoi anche allegare immagini e video a un elemento della sequenza temporale. Di seguito è riportato un esempio di come inserire un elemento della sequenza temporale con una foto allegata:
HTTP non elaborato
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()
Un elemento della sequenza temporale con un'immagine allegata è simile a questa su Glass:
Allegare video
Se alleghi file video agli elementi della sequenza temporale, ti consigliamo di guardare il video in streaming, anziché caricare l'intero payload in una sola volta. L'API Google Mirror supporta lo streaming con live streaming HTTP, download progressivo e protocollo in tempo reale (RTSP). RTSP è spesso bloccato dai firewall, quindi usa le altre opzioni quando possibile.
Per trasmettere in streaming il video, utilizza la voce di menu integrata PLAY_VIDEO
e specifica l'URL del video come voce del menu payload
. Per ulteriori informazioni, consulta la pagina Aggiungere voci del menu integrate e formati multimediali supportati.
Impaginazione
Puoi impaginare le voci della sequenza temporale che non rientrano in una singola scheda della sequenza temporale, ma devono essere associate alla stessa scheda. Gli elementi impaginati hanno tutti la stessa timeline.id
e pertanto hanno lo stesso insieme di voci di menu. Quando un utente tocca una voce della sequenza temporale impaginata, viene visualizzata una voce di menu Ulteriori informazioni.
Glass impagina automaticamente gli elementi della sequenza temporale che mostrano text
. Per fare in modo che Glass
impagina automaticamente html
, utilizza il
tag article
con la proprietà class impostata su auto-paginate
come nell'esempio seguente:
<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>
Per impaginare manualmente, utilizza il tag article
per i contenuti da visualizzare in ciascuna scheda. Glass visualizza i contenuti di ogni tag article
in una scheda di Spostamenti separata. Ad esempio, puoi creare un elemento della sequenza temporale con il seguente codice 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>
Per impostazione predefinita, la prima scheda dell'elemento della sequenza temporale viene visualizzata come scheda di copertina e nuovamente quando l'utente seleziona la voce di menu Ulteriori informazioni. Per evitare che la prima scheda venga visualizzata di nuovo dopo aver toccato Ulteriori informazioni, puoi specificare la classe CSS cover-only
per il primo tag <article>
:
<article class="cover-only">
...
La classe cover-only
supporta anche gli elementi della sequenza temporale con pagine automatiche:
<article class="auto-paginate cover-only">
...
Pacchettizzazione
Il raggruppamento ti consente di raggruppare elementi correlati ma separati, ad esempio per singoli messaggi in un thread di email. I pacchetti presentano una scheda di copertina principale che un utente tocca per visualizzare una sequenza temporale che contiene le altre schede. I pacchetti si distinguono dalle normali schede della sequenza temporale per un angolo piegato nell'angolo in alto a destra della scheda di copertina.
Per raggruppare elementi della sequenza temporale, creali con lo stesso valore per bundleId
. L'elemento aggiunto più di recente
è la copertina del bundle.
Le seguenti immagini mostrano una scheda di copertina in bundle con l'angolo piegato nell'angolo in alto a destra e due schede in bundle sotto.
Lettura degli elementi della sequenza temporale
Il servizio può accedere a tutti gli elementi della sequenza temporale che ha creato e a tutti gli elementi della sequenza temporale con cui sono stati condivisi. Ecco come elencare gli elementi della sequenza temporale che sono visibili al tuo servizio.
HTTP non elaborato
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()
Puoi utilizzare altre operazioni REST per ricevere, aggiornare ed eliminare le voci della sequenza temporale.
Accesso agli allegati
Puoi accedere agli allegati di un elemento della sequenza temporale tramite una proprietà dell'array denominata attachments
.
Puoi quindi ottenere i dati binari di un allegato tramite la proprietà contentUrl
dell'allegato o con l'endpoint degli allegati.
HTTP non elaborato
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();
Creazione delle voci di menu in corso...
Le voci di menu consentono agli utenti di richiedere azioni correlate alla scheda della sequenza temporale e sono di due tipi: voci di menu integrate e voci di menu personalizzate.
Le voci di menu integrate consentono di accedere alle funzionalità speciali fornite da Glass, ad esempio la lettura ad alta voce di una scheda della sequenza temporale, la navigazione in un luogo, la condivisione di un'immagine o la risposta a un messaggio:
Le voci di menu personalizzate consentono alla tua applicazione di esporre un comportamento specifico per il tuo Glassware e puoi anche fornire un'icona della voce di menu corrispondente al tuo branding.
Aggiungere voci del menu integrate
Puoi aggiungere voci di menu integrate agli elementi della sequenza temporale compilando
menuItems array
quando li inserisci.
Per utilizzare una voce di menu incorporata, devi completare solo
action
in ogni menuItem
.
HTTP non elaborato
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"
}
]
}
Definizione delle voci di menu personalizzate
Se le voci del menu integrate non funzionano, puoi creare voci di menu personalizzate eseguendo le tue azioni come segue quando inserisci o aggiorni una voce della sequenza temporale:
- Specifica
CUSTOM
permenuItem.action
. - Specifica un
menuItem.id
. Quando gli utenti toccano una voce di menu personalizzata, il tuo Glassware riceve una notifica che viene completata conmenuItem.id
. In questo modo puoi determinare l'origine della notifica. - Specifica
menuItem.values
per aggiungere un elementoiconUrl
edisplayName
visualizzato su Glass. Posiziona il puntatore del mouse su un'immagine PNG 50 x 50 di colore bianco con uno sfondo trasparente per l'elementoiconUrl
. Specifica un
displayTime
. Se non specifichi un elementodisplayTime
, la voce della sequenza temporale viene spostata in primo piano ogni volta che gli utenti toccano la voce di menu personalizzata.
HTTP non elaborato
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"
}]
}
]
}
Consentire agli utenti di bloccare la tua scheda della cronologia
Puoi creare una voce di menu che consenta agli utenti di fissare la scheda della cronologia, che viene visualizzata in modo permanente sulla sinistra della scheda dell'orologio principale. Gli utenti possono sbloccare la scheda anche utilizzando la stessa voce di menu.
La voce di menu di blocco è una voce di menu incorporata, perciò devi soltanto fornire la proprietà TOGGLE_PINNED
action
per una menuItem
.
HTTP non elaborato
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"
}
...
]
}
Iscrizioni
L'API Mirror consente di iscriversi alle notifiche inviate quando l'utente intraprende azioni specifiche su un elemento della sequenza temporale o quando la posizione dell'utente è stata aggiornata. Quando ti iscrivi a una notifica, devi fornire un URL di callback che elabora la notifica.
Ricezione notifiche
Una notifica dall'API Mirror viene inviata come richiesta POST
all'endpoint sottoscritto contenente un corpo della richiesta JSON
.
HTTP non elaborato
{
"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)
Il servizio deve rispondere all'API con un codice di stato HTTP 200 OK
se non si è verificato alcun errore.
Se il servizio risponde con un codice di errore, l'API Mirror potrebbe
provare a inviare nuovamente la notifica.
Tipi di notifiche
L'API Mirror invia un payload di notifica diverso per eventi diversi.
Rispondi
L'utente ha risposto alla tua voce della sequenza temporale utilizzando la voce di menu REPLY
integrata:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "INSERT",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "REPLY"
}
]
}
L'attributo itemId
è impostato sul valore ID
dell'articolo contenente:
- L'attributo
inReplyTo
è impostato suID
dell'elemento della sequenza temporale a cui si tratta di una risposta. - Attributo
text
impostato sulla trascrizione del testo. - L'attributo
recipients
impostato sucreator
dell'elemento della sequenza temporale a cui risponde, se esiste.
Esempio:
{
"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"
]
}
]
}
Elimina
L'utente ha eliminato un elemento della sequenza temporale:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "DELETE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "DELETE"
}
]
}
L'attributo itemId
è impostato sull'ID dell'elemento eliminato. L'elemento non contiene più metadati diversi dal suo ID e dalla proprietà isDeleted
.
Voce di menu personalizzata selezionata
L'utente ha selezionato una voce del menu personalizzata impostata dal servizio:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "UPDATE",
"userToken": "harold_penguin",
"userActions": [
{
"type": "CUSTOM",
"payload": "PING"
}
]
}
L'attributo itemId
è impostato sull'ID della voce di menu selezionata dall'utente.
L'array userActions
contiene l'elenco delle azioni personalizzate intraprese dall'utente per questo elemento. Il tuo servizio dovrebbe gestire tali azioni di conseguenza.
Aggiornamento posizione
È disponibile un nuovo percorso per l'utente corrente:
{
"collection": "locations",
"itemId": "latest",
"operation": "UPDATE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer"
}
Quando il Glassware riceve un aggiornamento della posizione, invia una richiesta all'endpoint glass.locations.get per recuperare la posizione nota più recente. Il tuo Glassware riceve gli aggiornamenti sulla posizione ogni dieci minuti.
Comando vocale
L'utente ha attivato un comando vocale, ad esempio: "Ok Glass, crea una nota, Cat Stream, il compleanno di Chipotle è domani domani". Al tuo Glasswareware viene inviata la seguente notifica:
{
"collection": "timeline",
"operation": "INSERT",
"userToken": "chipotle's_owner",
"verifyToken": "mew mew mew",
"itemId": "<ITEM_ID>",
"userActions": [
{“type”: "LAUNCH"}
]
}
Questa notifica si distingue dalle altre per il valore LAUNCH
nella proprietà userActions
.
Puoi quindi utilizzare il valore del tag itemId
per recuperare l'elemento della sequenza temporale:
{
"id": "<ITEM_ID>",
"text": "Chipotle's birthday is tomorrow",
"recipients": [
{"id": "CAT_STREAM"}
]
}
La proprietà recipients
contiene il id
del contatto che rappresenta il comando vocale utilizzato.