Mit einfachen 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 Standort oder Medien anhängen.
Funktionsweise
Statische Karten werden standardmäßig rechts neben der Uhr auf Glass angezeigt und enthalten Informationen, die für den Nutzer zum Zeitpunkt der Auslieferung relevant sind. Im Gegensatz zu Live-Karten erfordern sie jedoch keine sofortige Aufmerksamkeit und Nutzer können die Karte lesen oder darauf reagieren wann immer sie möchten.

Wenn Glassware statische Karten in die Zeitachse einfügt, kann Glass einen Benachrichtigungston abspielen, um Nutzer zu benachrichtigen. Alle vorherigen statischen Karten werden ebenfalls nach rechts verschoben und nach 7 Tagen oder wenn 200 neuere Karten vorhanden sind, aus der Zeitachse entfernt.
Verwendung
Statische Karten eignen sich hervorragend, um Nutzern regelmäßig Benachrichtigungen zu wichtigen Ereignissen zu senden.
Beispiel: Ein Nachrichtendienst, der die wichtigsten Nachrichten sendet, sobald sie eintreffen. Mit statischen Karten der Mirror API
können auch Live-Karten oder
immersiven Inhalte über den
OPEN_URI
Menüpunkt gestartet werden. So können Sie hybride Interaktionen erstellen, bei denen statische Karten als Benachrichtigungen und eine Live-Karte oder immersive Inhalte für eine interaktivere Erfahrung verwendet werden.
Eine vollständige Liste der möglichen Vorgänge für Zeitachsenelemente finden Sie in der Referenz dokumentation.
Statische Karten einfügen
Wenn Sie statische Karten (Zeitachsenelemente) einfügen möchten, senden Sie eine JSON-Darstellung eines Zeitachsenelements an den REST-Endpunkt.
Die meisten Felder in einem Zeitachsenelement sind optional. In der einfachsten Form enthält ein Zeitachsenelement nur eine kurze Textnachricht, wie in diesem Beispiel:
Raw 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()
Wenn der Vorgang erfolgreich war, erhalten Sie den Antwortcode 201 Created mit einer vollständigen Kopie des erstellten Elements. Für das vorherige Beispiel könnte eine erfolgreiche Antwort so aussehen:
Raw 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, was viel mehr ist, als in ein Zeitachsenelement passt. Aus diesem Grund können Sie einem Zeitachsenelement auch Bilder und Videos anhängen. Hier ein Beispiel für das Einfügen eines Zeitachsenelements mit einem Fotoanhang:
Raw 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 einem angehängten Bild sieht auf Glass ungefähr so aus:

Video anhängen
Wenn Sie Ihren Zeitachsenelementen Videodateien anhängen, empfehlen wir, das Video zu streamen, anstatt die gesamte Nutzlast auf einmal hochzuladen. Die Google Mirror API unterstützt Streaming mit HTTP Live Streaming, Progressive Download und dem Real Time 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 PLAY_VIDEO
integrierten Menüpunkt und geben Sie die URL des Videos als
payload des Menüpunkts an. Weitere Informationen finden Sie unter
Integrierte Menüpunkte hinzufügen und
Unterstützte Media-Formate.
Paginierung
Sie können Zeitachsenelemente paginieren, die nicht auf eine einzelne Zeitachsenkarte passen, aber ansonsten mit derselben Karte verknüpft sein sollten. Paginierte
Elemente haben alle dieselbe timeline.id und daher dieselben
Menüpunkte. Wenn ein Nutzer auf ein paginiertes Zeitachsenelement tippt, wird der Menüpunkt Mehr lesen angezeigt.
Glass paginiert automatisch Zeitachsenelemente, die
text enthalten. Wenn Glass automatisch
paginieren html soll, verwenden Sie das article
Tag mit der auf auto-paginate gesetzten Klassen-Property, 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 manuell paginieren möchten, verwenden Sie das Tag article für die Inhalte, die auf jeder Karte angezeigt werden sollen. Glass zeigt die Inhalte jedes article-Tags auf einer separaten Unterkarte der Zeitachse an. Sie können beispielsweise ein paginiertes Zeitachsenelement mit dem folgenden HTML-Code 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 paginierten Zeitachsenelements als Coverkarte angezeigt und noch einmal, wenn der Nutzer den Menüpunkt Mehr lesen auswählt. Wenn Sie verhindern möchten, dass die erste Karte nach dem Tippen auf
Mehr lesen noch einmal angezeigt wird, können Sie die cover-only CSS-Klasse für das erste
<article> Tag angeben:
<article class="cover-only">
...
Die Klasse cover-only unterstützt auch automatisch paginierte Zeitachsenelemente:
<article class="auto-paginate cover-only">
...
Gruppieren
Mit der Gruppierung können Sie verwandte, aber unterschiedliche Elemente zusammenfassen, z. B. einzelne Nachrichten in einem E‑Mail-Thread. Gruppen haben eine Hauptcoverkarte, auf die ein Nutzer tippt, um eine Unterkarte der Zeitachse mit den anderen Karten in der Gruppe anzuzeigen. Gruppen unterscheiden sich von normalen Zeitachsenkarten durch eine Ecke oben rechts auf der Coverkarte der Gruppe.
Wenn Sie Zeitachsenelemente gruppieren möchten, erstellen Sie sie mit demselben Wert für
bundleId. Das zuletzt hinzugefügte Element ist die Coverkarte der Gruppe.
Die folgenden Bilder zeigen eine Coverkarte der Gruppe mit der Ecke oben rechts und zwei gruppierte 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 Zeitachsenelemente auf, die für Ihren Dienst sichtbar sind:
Raw 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()
Sie können andere REST-Vorgänge verwenden, um Zeitachsenelemente abzurufen, zu aktualisieren und zu lö5schen.
Auf Anhänge zugreifen
Sie können über
eine Array-Property namens attachments auf Anhänge eines Zeitachsenelements zugreifen.
Anschließend können Sie die Binärdaten eines Anhangs über die
contentUrl
Property des Anhangs oder mit dem
Endpunkt für Anhängeabrufen.
Raw 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
Mit Menüpunkten können Nutzer Aktionen anfordern, die mit der Zeitachsenkarte verknüpft sind. Es gibt zwei Arten von Menüpunkten: integrierte und benutzerdefinierte.
Integrierte Menüpunkte bieten Zugriff auf spezielle Funktionen von Glass, z. B. das Vorlesen einer Zeitachsenkarte, das Navigieren zu einem Standort, das Teilen eines Bildes oder das Antworten auf eine Nachricht:

Mit benutzerdefinierten Menüpunkten können Sie in Ihrer Anwendung ein Verhalten festlegen, das speziell für Ihre Glassware gilt. Außerdem können Sie ein Menüpunktsymbol bereitstellen, das zu Ihrem Branding passt.
Integrierte Menüpunkte hinzufügen
Sie können Ihren Zeitachsenelementen integrierte Menüpunkte hinzufügen, indem Sie beim Einfügen das
menuItems array ausfüllen.
Wenn Sie einen integrierten Menüpunkt verwenden möchten, müssen Sie nur die
action jedes menuItem ausfüllen.
Raw 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 integrierte Menüpunkte für Sie nicht geeignet sind, können Sie benutzerdefinierte Menüpunkte mit eigenen Aktionen erstellen. Gehen Sie dazu beim Einfügen oder Aktualisieren eines Zeitachsenelements so vor:
- Geben Sie für
menuItem.actiondie OptionCUSTOMan. - Geben Sie eine
menuItem.idan. Wenn Nutzer auf den benutzerdefinierten Menüpunkt tippen, erhält Ihre Glassware eine Benachrichtigung mit der ausgefülltenmenuItem.id. So können Sie die Quelle der Benachrichtigung ermitteln. - Geben Sie
menuItem.valuesan, um eineiconUrlund einendisplayNamehinzuzufügen, die auf Glass angezeigt werden. Geben Sie für dieiconUrlein 50 × 50 großes PNG-Bild an, das weiß mit transparentem Hintergrund ist. Geben Sie eine
displayTimean. Wenn Sie keinedisplayTimeangeben, wird das Zeitachsenelement immer dann an den Anfang der Zeitachse verschoben, wenn Nutzer auf den benutzerdefinierten Menüpunkt tippen.
Raw 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 Zeitachsenkarte anpinnen können. Dadurch wird die Zeitachsenkarte dauerhaft links neben der Hauptuhrkarte angezeigt. Nutzer können die Karte auch wieder lösen, indem sie denselben Menüpunkt verwenden.
Der Menüpunkt zum Anpinnen ist ein integrierter Menüpunkt. Sie müssen also nur die TOGGLE_PINNED
action für ein menuItem angeben.
Raw 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 können Sie Benachrichtigungen abonnieren , die gesendet werden, wenn der Nutzer bestimmte Aktionen für ein Zeitachsenelement ausführt oder wenn der Standort des Nutzers aktualisiert wurde. Wenn Sie eine Benachrichtigung abonnieren, geben Sie eine Callback-URL an, die die Benachrichtigung verarbeitet.
Benachrichtigungen erhalten
Eine Benachrichtigung von der Mirror API wird als POST-Anfrage an den abonnierten Endpunkt gesendet und enthält einen JSON-Anfragetext.
Raw 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)
Ihr Dienst muss der API mit dem HTTP-Statuscode 200 OK antworten, wenn kein Fehler aufgetreten ist.
Wenn Ihr Dienst mit einem Fehlercode antwortet, versucht die Mirror API möglicherweise, die Benachrichtigung noch einmal an Ihren Dienst zu senden.
Benachrichtigungstypen
Die Mirror API sendet für verschiedene Ereignisse unterschiedliche Benachrichtigungsnutzlasten.
Antworten
Der Nutzer hat mit dem integrierten Menüpunkt REPLY auf Ihr Zeitachsenelement geantwortet:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "INSERT",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "REPLY"
}
]
}
Das Attribut itemId ist auf die ID des Elements gesetzt, das Folgendes enthält:
- Das Attribut
inReplyToist auf dieIDdes Zeitachsenelements gesetzt, auf das geantwortet wird. - Das Attribut
textist auf die Texttranskription gesetzt. - Das Attribut
recipientsist auf dencreatordes Zeitachsenelements gesetzt, auf das geantwortet wird, falls 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 gesetzt. Das Element enthält keine anderen Metadaten als seine ID und die
isDeleted Property.
Benutzerdefinierter Menüpunkt ausgewählt
Der Nutzer hat einen benutzerdefinierten Menüpunkt ausgewählt, der von Ihrem 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 gesetzt, 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.
Standort-Update
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 ein Standort-Update erhält, senden Sie eine Anfrage an den glass.locations.get , um den letzten bekannten Standort abzurufen. Ihre Glassware erhält alle zehn Minuten Standortaktualisierungen.
Sprachbefehl
Ihr Nutzer hat einen Sprachbefehl aktiviert, z. B. „Ok Glass, notiere, Cat Stream, Chipotles Geburtstag ist morgen“. Die folgende Benachrichtigung wird an Ihre Glassware 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 userActions Property.
Sie können 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, der den verwendeten Sprachbefehl darstellt.