Mithilfe einfacher REST APIs können Sie statische Karten einfügen, aktualisieren, lesen und löschen. Außerdem können Sie einer statischen Karte Objekte wie einen Ort oder Medien anhängen.
Funktionsweise
Statische Karten werden standardmäßig rechts neben der Uhr angezeigt und enthalten Informationen, die für den Nutzer zum Zeitpunkt der Zustellung relevant sind. Sie erfordern jedoch nicht wie Livekarten sofortige Aufmerksamkeit und Nutzer können die Karte in Ruhe lesen oder die darin enthaltenen Informationen nutzen.
Wenn Glassware statische Karten in die Zeitachse einfügt, kann Glass einen Benachrichtigungston abspielen, um Nutzer zu informieren. Alle vorherigen statischen Karten werden ebenfalls nach rechts verschoben und verschwinden nach 7 Tagen oder wenn 200 Karten neuer sind.
Verwendung
Mithilfe von statischen Karten können Sie Nutzern regelmäßige Benachrichtigungen senden, wenn etwas Wichtiges passiert.
Beispiel: Ein Nachrichtendienst, der die wichtigsten Nachrichten in Echtzeit sendet. Über das Menüelement OPEN_URI
können Sie auch Livekarten oder Immersionen über statische Mirror API-Karten starten. So können Sie hybride Interaktionen erstellen, bei denen statische Karten als Benachrichtigungen und eine Livekarte oder ein immersiver Modus für eine interaktivere Nutzung verwendet werden.
Eine vollständige Liste der möglichen Vorgänge für Zeitachsenelemente finden Sie in der Referenzdokumentation.
Statische Karten einfügen
Wenn du statische Karten (Zeitachsenelemente) einfügen möchtest, POSTE eine JSON-Darstellung eines Zeitachsenelements an den REST-Endpunkt.
Die meisten Felder in einem Zeitachsenelement sind optional. In seiner einfachsten Form enthält ein Zeitachsenelement nur eine kurze Textnachricht, wie in diesem Beispiel:
Roh-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()
Bei Erfolg erhalten Sie einen 201 Created
-Antwortcode mit einer vollständigen Kopie des erstellten Elements. Für das vorherige Beispiel könnte eine erfolgreiche Antwort so aussehen:
Roh-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"
}
Das eingefügte Element, das in der Zeitachse des Nutzers angezeigt wird, sieht so aus:
Zeitachsenelement mit Anhang einfügen
Ein Bild sagt mehr als tausend Worte – und das ist viel mehr, als in ein Zeitachsenelement passt. Dazu können Sie einem Zeitachsenelement auch Bilder und Videos anhängen. Hier ein Beispiel für das Einfügen eines Zeitachsenelements mit einem angehängten Foto:
Roh-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()
Ein Zeitachsenelement mit angehängtem Bild sieht auf Google Glass in etwa so aus:
Video anhängen
Wenn du Videodateien an deine Zeitachsenelemente anfügst, empfehlen wir, das Video zu streamen, anstatt die gesamte Nutzlast auf einmal hochzuladen. Die Google Mirror API unterstützt Streaming mit HTTP Live Streaming, progressivem Download und dem Realtime Streaming Protocol (RTSP). RTSP wird häufig von Firewalls blockiert. Verwenden Sie daher nach Möglichkeit die anderen Optionen.
Wenn Sie ein Video streamen möchten, verwenden Sie den integrierten Menüpunkt PLAY_VIDEO
und geben Sie die URL des Videos als payload
des Menüpunkts an. Weitere Informationen finden Sie unter Vordefinierte Menüpunkte hinzufügen und Unterstützte Medienformate.
Paginierung
Sie können Zeitachsenelemente, die nicht auf eine einzelne Zeitachsenkarte passen, aber ansonsten mit derselben Karte verknüpft werden sollten, auf mehrere Seiten aufteilen. Alle Seiten mit Paginierung haben dieselbe timeline.id
und daher dieselben Menüpunkte. Wenn ein Nutzer auf ein paginarisiertes Zeitachsenelement tippt, wird der Menüpunkt Weitere Informationen angezeigt.
Die Zeitachsenelemente, die text
enthalten, werden von Glass automatisch paginiert. Wenn Glass html
automatisch auf mehrere Seiten aufteilen soll, verwenden Sie das article
-Tag mit der Klasseneigenschaft auto-paginate
, wie im folgenden Beispiel:
<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>
Wenn Sie die Paginierung manuell vornehmen möchten, verwenden Sie das article
-Tag für den Inhalt, der auf jeder Karte angezeigt werden soll. Glass zeigt den Inhalt jedes article
-Tags auf einer separaten Karte in der Zeitleiste an. Mit dem folgenden HTML-Code kannst du beispielsweise ein paginarisiertes Zeitleistenelement erstellen:
<article>
<section>
<p>First page</p>
</section>
</article>
<article>
<section>
<p>Second page</p>
</section>
</article>
<article>
<section>
<p>Third page</p>
</section>
</article>
Standardmäßig wird die erste Karte des paginaten Zeitachsenelements als Titelkarte angezeigt und noch einmal, wenn der Nutzer den Menüpunkt Mehr anzeigen auswählt. Wenn die erste Karte nicht mehr angezeigt werden soll, nachdem auf Weitere Informationen getippt wurde, können Sie die CSS-Klasse cover-only
für das erste <article>
-Tag angeben:
<article class="cover-only">
...
Die cover-only
-Klasse unterstützt auch automatisch paginaierte Zeitachsenelemente:
<article class="auto-paginate cover-only">
...
Bündelung
Mit Bündeln können Sie ähnliche, aber unterschiedliche Elemente gruppieren, z. B. einzelne Nachrichten in einem E-Mail-Thread. Sets haben eine Haupt-Coverkarte, auf die Nutzer tippen können, um eine untergeordnete Zeitachse mit den anderen Karten im Set aufzurufen. Sets unterscheiden sich von normalen Zeitachsenkarten durch eine Ecke oben rechts auf der Titelkarte des Sets.
Wenn du Zeitachsenelemente bündeln möchtest, gib für sie denselben Wert für bundleId
ein. Das zuletzt hinzugefügte Element ist die Titelkarte des Sets.
Die folgenden Bilder zeigen eine Set-Coverkarte mit der Ecke oben rechts und zwei Set-Karten darunter.
Zeitachsenelemente lesen
Ihr Dienst kann auf alle Zeitachsenelemente zugreifen, die er erstellt hat, und auf alle Zeitachsenelemente, die für ihn freigegeben wurden. So listen Sie die Zeitleistenelemente auf, die für Ihren Dienst sichtbar sind.
Roh-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()
Mit anderen REST-Vorgängen können Sie Zeitachsenelemente abrufen, aktualisieren und löschen.
Auf Anhänge zugreifen
Sie können über eine Array-Property namens attachments
auf Anhänge zu einem Zeitachsenelement zugreifen.
Sie können die Binärdaten eines Anhangs dann über das Attribut contentUrl
des Anhangs oder über den Anhängeendpunkt abrufen.
Roh-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();
Menüpunkte erstellen
Über Menüpunkte können Nutzer Aktionen anfordern, die sich auf die Zeitachsenkarte beziehen. Es gibt zwei Arten von Menüpunkten: integrierte Menüpunkte und benutzerdefinierte Menüpunkte.
Über die integrierten Menüpunkte können Sie auf spezielle Funktionen von Glass zugreifen, z. B. eine Zeitachsenkarte vorlesen, zu einem Ort navigieren, ein Bild teilen oder auf eine Nachricht antworten:
Mit benutzerdefinierten Menüpunkten können Sie in Ihrer Anwendung ein Verhalten festlegen, das für Ihr Glassware-Produkt spezifisch ist. Außerdem können Sie ein Menüpunktsymbol bereitstellen, das zu Ihrem Branding passt.
Vordefinierte Menüpunkte hinzufügen
Sie können Ihren Zeitleistenelementen integrierte Menüpunkte hinzufügen, indem Sie beim Einfügen den Platzhalter menuItems array
ausfüllen.
Wenn Sie einen vordefinierten Menüpunkt verwenden möchten, müssen Sie nur die action
jedes menuItem
ausfüllen.
Roh-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"
}
]
}
Benutzerdefinierte Menüpunkte definieren
Wenn die vordefinierten Menüpunkte nicht für Sie geeignet sind, können Sie benutzerdefinierte Menüpunkte mit eigenen Aktionen erstellen. Gehen Sie dazu so vor, wenn Sie ein Zeitachsenelement einfügen oder aktualisieren:
- Geben Sie
CUSTOM
fürmenuItem.action
an. - Geben Sie eine
menuItem.id
an. Wenn Nutzer auf den benutzerdefinierten Menüpunkt tippen, wird in Ihrem Glassware-Konto eine Benachrichtigung mitmenuItem.id
gesendet. So können Sie die Quelle der Benachrichtigung ermitteln. - Geben Sie
menuItem.values
an, um einiconUrl
und eindisplayName
hinzuzufügen, das auf Google Glass angezeigt wird. Verweisen Sie für dasiconUrl
auf ein weißes PNG-Bild mit einem transparenten Hintergrund und einer Größe von 50 × 50 Pixeln. Geben Sie eine
displayTime
an. Wenn Sie keindisplayTime
angeben, wird das Zeitachsenelement an den Anfang der Zeitachse verschoben, wenn Nutzer auf den benutzerdefinierten Menüpunkt tippen.
Roh-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"
}]
}
]
}
Nutzern erlauben, Ihre Zeitachsenkarte anzupinnen
Sie können einen Menüpunkt erstellen, mit dem Nutzer die Zeitachse anpinnen können. Dadurch wird die Zeitachse dauerhaft links neben der Hauptuhrkarte angezeigt. Nutzer können die Karte auch über dasselbe Menüelement loslösen.
Der Menüpunkt „Anpinnen“ ist ein vordefinierter Menüpunkt. Sie müssen also nur TOGGLE_PINNED
action
für eine menuItem
angeben.
Roh-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"
}
...
]
}
Abos
Mit der Mirror API kannst du Benachrichtigungen abonnieren, die gesendet werden, wenn der Nutzer bestimmte Aktionen auf einem Zeitachsenelement ausführt oder sein Standort aktualisiert wurde. Wenn Sie eine Benachrichtigung abonnieren, geben Sie eine Rückruf-URL an, über die die Benachrichtigung verarbeitet wird.
Benachrichtigungen erhalten
Eine Benachrichtigung von der Mirror API wird als POST
-Anfrage mit einem JSON
-Anfragetext an den abonnierten Endpunkt gesendet.
Roh-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)
Dein Dienst muss der API mit dem HTTP-Statuscode 200 OK
antworten, wenn kein Fehler aufgetreten ist.
Wenn dein Dienst mit einem Fehlercode antwortet, versucht die Mirror API möglicherweise, die Benachrichtigung noch einmal an deinen Dienst zu senden.
Benachrichtigungstypen
Die Mirror API sendet für verschiedene Ereignisse eine unterschiedliche Benachrichtigungsnutzlast.
Antworten
Der Nutzer hat über den integrierten Menüpunkt REPLY
auf deinen Zeitachseneintrag geantwortet:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "INSERT",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "REPLY"
}
]
}
Das itemId
-Attribut ist auf die ID
des Elements festgelegt, das Folgendes enthält:
- Das Attribut
inReplyTo
ist auf dasID
des Zeitachsenelements festgelegt, auf das geantwortet wird. - Das
text
-Attribut ist auf die Texttranskription festgelegt. - Das Attribut
recipients
ist auf dascreator
des Zeitachsenelements festgelegt, auf das es sich bezieht, sofern vorhanden.
Beispiel:
{
"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"
]
}
]
}
Löschen
Der Nutzer hat ein Zeitachsenelement gelöscht:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "DELETE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "DELETE"
}
]
}
Das Attribut itemId
ist auf die ID des gelöschten Elements festgelegt. Das Element enthält keine anderen Metadaten als seine ID und die Property isDeleted
.
Benutzerdefinierter Menüpunkt ausgewählt
Der Nutzer hat einen benutzerdefinierten Menüpunkt ausgewählt, der von deinem Dienst festgelegt wurde:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "UPDATE",
"userToken": "harold_penguin",
"userActions": [
{
"type": "CUSTOM",
"payload": "PING"
}
]
}
Das Attribut itemId
ist auf die ID des Menüpunkts festgelegt, den der Nutzer ausgewählt hat.
Das Array userActions
enthält die Liste der benutzerdefinierten Aktionen, die der Nutzer für dieses Element ausgeführt hat. Ihr Dienst sollte diese Aktionen entsprechend verarbeiten.
Standortaktualisierung
Für den aktuellen Nutzer ist ein neuer Standort verfügbar:
{
"collection": "locations",
"itemId": "latest",
"operation": "UPDATE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer"
}
Wenn Ihre Glassware-Anwendung ein Standortupdate erhält, senden Sie eine Anfrage an den Endpunkt glass.locations.get, um den aktuellsten bekannten Standort abzurufen. Ihr Glassware-Gerät erhält alle zehn Minuten Standortaktualisierungen.
Sprachbefehl
Der Nutzer hat einen Sprachbefehl aktiviert, z. B.: „Hey Glass, mach mir eine Notiz: Cat Stream, Chipotles Geburtstag ist morgen.“ Die folgende Benachrichtigung wird an Ihr Glassware-Gerät gesendet:
{
"collection": "timeline",
"operation": "INSERT",
"userToken": "chipotle's_owner",
"verifyToken": "mew mew mew",
"itemId": "<ITEM_ID>",
"userActions": [
{“type”: "LAUNCH"}
]
}
Diese Benachrichtigung unterscheidet sich von anderen Benachrichtigungen durch den LAUNCH
-Wert in der Property userActions
.
Du kannst dann den Wert in itemId
verwenden, um das Zeitachsenelement abzurufen:
{
"id": "<ITEM_ID>",
"text": "Chipotle's birthday is tomorrow",
"recipients": [
{"id": "CAT_STREAM"}
]
}
Die Property recipients
enthält die id
des Kontakts, die den verwendeten Sprachbefehl darstellt.