静态卡片

您可以使用简单的 REST API。此外,您还可以将对象附加到静态卡上,例如 作为营业地点或媒体

运作方式

静态卡片默认位于 Glass 时钟右侧,并显示信息 确保与用户的内容相关。不过,它们不要求 即时关注,例如实时卡片 而且用户可以选择阅读卡片 空闲时间。

当 Glassware 将静态卡片插入时间轴时,Glass 可能会播放通知 提醒用户的声音之前的所有静态卡片也会向右移动 在 7 天后或当 200 张新卡较新时,该卡片就会从时间轴上消失。

何时使用此类附加信息

静态卡非常适合用于 定期通知 重要的事情发生时向用户展示 例如,一项新闻传送服务 及时发送热门新闻报道。镜像 API 静态卡片 还可以启动实时卡片 沉浸感 OPEN_URI 。这样,你就可以创建利用 静态卡片作为通知,而实时卡片或沉浸感 更具互动性的体验

有关时间轴项的可能操作的完整列表,请参阅参考文档 文档

插入静态卡片

插入静态卡片(时间轴项目),请在 时间轴项的 JSON 表示法 REST 端点

时间轴项中的大多数字段都是选填的。简单来说, 时间轴项仅包含一条简短的文本消息,如下例所示:

原始 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()

成功后,您会收到包含如下内容的 201 Created 响应代码: 所创建项的完整副本。对于上一个示例,成功响应 可能如下所示:

原始 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"
}

插入的内容将出现在用户时间轴中,如下所示:

插入带有附件的时间轴项

一张好图胜过千言万语,一张张说得上的内容远胜在 时间轴项。为此,您还可以附加图片和视频 添加到时间轴项下例说明了如何在 照片附件:

原始 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()

附加了图片的时间轴项在 Google Glass 上如下所示:

正在附加视频

如果您要向时间轴项附加视频文件,我们建议您 而不是一次性上传整个载荷。 Google Mirror API 支持通过 HTTP 实时流式传输、 渐进式下载和实时流式传输协议 (RTSP)。 RTSP 经常被防火墙阻止,因此当出现以下情况时,请使用其他选项:

如需流式传输视频,请使用 PLAY_VIDEO 内置菜单项,并将视频网址指定为该菜单项的 payload。请参阅 添加内置菜单项 支持的媒体格式

正在分页

您可以对无法在单个时间轴卡片上容纳的时间轴项进行分页, 但应与此卡相关联分页 项共享相同的 timeline.id,因此具有 同一组菜单项。当用户点按分页的时间轴项时, 系统会显示阅读更多菜单项。

Glass 会自动将显示的时间轴项分页 text。让 Google Glass 自动运行 对 html 进行分页,使用 article 标记的类,其类属性设置为 auto-paginate,如以下示例所示:

<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>

如需手动分页,请为内容使用 article 标记 您希望在每张卡片上显示的具体名称Glass 会显示每台设备的内容 单独的子时间轴卡片中的 article 标记。例如,您可以创建一个 包含以下 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>

默认情况下,分页时间轴项的第一张卡片显示为 封面卡片,并且会在用户选择阅读更多 。防止点按后第一张卡片再次显示 了解详情,您可以为第一个cover-only <article> 标记:

<article class="cover-only">
...

cover-only 类还支持自动分页时间轴项:

<article class="auto-paginate cover-only">
...

分类显示

利用分类功能,您可以将相关但又截然不同的内容归为一组,例如 单独的邮件。媒体包中有一张主封面卡片 用户点按来显示一个子时间轴,其中包含套装中的其他卡片。 媒体包与普通时间轴卡片的区别在于,媒体包在上方有一角折痕 。

若要捆绑时间轴项,请创建具有相同值的 bundleId。最近添加 是套装的封面卡片。

以下图片展示了一个套装 右上角有折角的封面卡片,其中两张捆绑在一起 卡片下方

读取时间轴项

您的服务可以访问它创建的所有时间轴项,以及所有时间轴 与其共享的内容的数量。具体方法如下: 列出 对你的服务可见

原始 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()

您可以使用其他 REST 操作来获取update删除时间轴项。

访问附件

您可以通过以下方式访问时间轴内容的附件: 一个名为 attachments 的数组属性。 然后,您可以通过 contentUrl 属性或 连接端点

原始 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();

创建菜单项

通过菜单项,用户可以请求与时间轴卡、 有两种类型:内置菜单项和自定义菜单项。

通过内置菜单项,您可以使用 眼镜,例如大声朗读时间轴卡片、导航到 位置信息、分享图片或回复消息:

自定义菜单项允许您的应用显示 与您的 Glassware 集成,也可提供一个 菜单项图标, 品牌塑造。

添加内置菜单项

您可以向时间轴项添加内置菜单项,只需在 menuItems array。 要使用内置菜单项,您只需要填充 每个 menuItemaction

原始 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"
    }
  ]
}

定义自定义菜单项

如果内置菜单项对您来说不适用,您可以使用 在插入或更新时间轴项时执行以下操作:

  • menuItem.action 指定 CUSTOM
  • 请指定 menuItem.id。当用户点按该自定义菜单项时,您的 Glassware 收到一条通知 已填充 menuItem.id。这样,您就可以确定 通知。
  • 指定 menuItem.values 以添加 iconUrl, 出现在 Glass 上的displayName。指向一个 50 x 50 的 PNG iconUrl 采用透明背景的白色图片。
  • 请指定 displayTime。如果您未指定 displayTime,则时间轴项 每当用户点按自定义菜单项时,它都会移至时间轴前面。

原始 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"
      }]
    }
  ]
}

允许用户固定您的时间轴卡片

您可以创建一个菜单项,让用户能够固定时间轴卡片 该时间轴会始终显示在 时钟卡片。用户也可以使用相同的菜单取消固定卡片 内容。

固定菜单项是内置菜单项,因此您只需提供 TOGGLE_PINNED action,表示 menuItem

原始 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"
    }
  ...
 ]
}

订阅

利用 Mirror API,您可以 订阅通知 当用户对某个网页执行特定操作时发送 时间轴项或用户所在位置 已更新。订阅通知后 提供用于处理通知的回调网址。

接收通知

Mirror API 会以 POST 请求的形式向 包含 JSON 请求正文的订阅端点。

原始 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)

您的服务必须以 200 OK HTTP 状态响应该 API 代码。 如果您的服务返回错误代码,Mirror API 可能会 请尝试向您的服务重新发送通知。

通知类型

Mirror API 会针对不同的事件发送不同的通知载荷。

回复

用户已使用内置的 REPLY 回复了您的时间轴项 菜单项:

{
  "collection": "timeline",
  "itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
  "operation": "INSERT",
  "userToken": "harold_penguin",
  "verifyToken": "random_hash_to_verify_referer",
  "userActions": [
    {
      "type": "REPLY"
    }
  ]
}

itemId 属性设置为包含以下各项的商品的 ID

  • inReplyTo 属性设置为其所属的时间轴项目的 ID 回复。
  • text 属性设为文本转录。
  • recipients 属性设置为它的时间轴项的 creator。 是对 的回复(如果存在)。

示例:

{
  "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"
      ]
    }
  ]
}

删除

用户已删除时间轴项:

{
  "collection": "timeline",
  "itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
  "operation": "DELETE",
  "userToken": "harold_penguin",
  "verifyToken": "random_hash_to_verify_referer",
  "userActions": [
    {
      "type": "DELETE"
    }
  ]
}

itemId 属性设置为已删除 内容。作品不再包含除 ID 和 isDeleted 属性。

已选择自定义菜单项

用户选择了一个 自定义菜单项 由您的服务设置:

{
  "collection": "timeline",
  "itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
  "operation": "UPDATE",
  "userToken": "harold_penguin",
  "userActions": [
    {
      "type": "CUSTOM",
      "payload": "PING"
    }
  ]
}

itemId 属性设置为 用户所选的内容。

userActions 数组包含自定义操作列表 用户对此商品采取的行动。您的服务应该处理 执行相应的操作

位置信息更新

新位置可供当前用户使用:

{
  "collection": "locations",
  "itemId": "latest",
  "operation": "UPDATE",
  "userToken": "harold_penguin",
  "verifyToken": "random_hash_to_verify_referer"
}

当您的 Glassware 收到位置更新时,请发送 向 glass.locations.get 端点检索最新的已知位置。您的玻璃器皿 每十分钟接收一次位置更新。

语音命令

您的用户激活了语音指令,例如: “Ok Glass,添加记事,Cat Stream,Chipotle 的生日是 明天”。以下通知会发送到您的 玻璃器皿:

{
  "collection": "timeline",
  "operation": "INSERT",
  "userToken": "chipotle's_owner",
  "verifyToken": "mew mew mew",
  "itemId": "<ITEM_ID>",
  "userActions": [
    {type: "LAUNCH"}
  ]
}

这种通知与其他通知的区别在于 LAUNCH 值。 在 userActions 属性中。

然后,您可以使用 itemId 中的值来提取时间轴项:

{
  "id": "<ITEM_ID>",
  "text": "Chipotle's birthday is tomorrow",
  "recipients": [
    {"id": "CAT_STREAM"}
  ]
}

recipients 属性包含代表id 使用语音指令。