البطاقات الثابتة

يمكنك إدراج بطاقات ثابتة وتعديلها وقراءتها وحذفها باستخدام طريقة واجهات برمجة تطبيقات REST. بالإضافة إلى ذلك، يمكنك إرفاق عناصر ببطاقة ثابتة، مثل كموقع جغرافي أو وسائط.

آلية عملها

توجد البطاقات الثابتة على يمين الساعة الزجاجية بشكل افتراضي وتعرض المعلومات وذات صلة بالمستخدم في وقت التسليم. ومع ذلك، فهي لا تتطلب اهتمام فوري، مثل البطاقات المباشرة ويمكن للمستخدمين اختيار قراءة البطاقة أو اتخاذ إجراء بشأنها في وقت فراغه.

عندما تدرج Glassware بطاقات ثابتة في المخطط الزمني، فقد يشغِّل Glass إشعارًا الصوت لتنبيه المستخدمين. تنتقل جميع البطاقات الثابتة السابقة أيضًا إلى اليمين وتختفي من المخطط الزمني بعد 7 أيام أو عند طرح 200 بطاقة أحدث.

حالات الاستخدام

تعد البطاقات الثابتة وسيلة رائعة لإرسال المحتوى الإشعارات الدورية للمستخدمين عند حدوث أشياء مهمة. على سبيل المثال، إحدى خدمات توصيل الأخبار التي أهم القصص الإخبارية فور حدوثها. البطاقات الثابتة في Mirror 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()

عنصر مخطط زمني مع صورة مرفقة يبدو على النحو التالي على Glass:

جارٍ إرفاق الفيديو

في حال إرفاق ملفات فيديو بعناصر المخطط الزمني، ننصحك بث الفيديو مباشرةً بدلاً من تحميل كامل البيانات دفعة واحدة تتيح واجهة برمجة التطبيقات Google Mirror API البث المباشر عبر بروتوكول HTTP والتنزيل التدريجي وبروتوكول البث في الوقت الفعلي (RTSP). غالبًا ما يتم حظر بروتوكول RTSP بواسطة جدران الحماية، لذا يمكنك استخدام الخيارات الأخرى عند ممكن.

لبث الفيديو، استخدِم PLAY_VIDEO. عنصر قائمة مدمج وتحديد عنوان URL للفيديو ليكون عنصر القائمة payload عرض إضافة عناصر القائمة المضمنة تنسيقات الوسائط المتوافقة لمزيد من المعلومات.

التقسيم على صفحات

يمكنك تقسيم عناصر المخطط الزمني التي لا تناسب أي بطاقة مخطط زمني واحد، ولكن يجب ربطها بالبطاقة نفسها بطريقة أخرى. مقسّم على صفحات تشترك جميع العناصر في timeline.id نفسها، وبالتالي تحتوي على نفس مجموعة عناصر القائمة. عندما ينقر المستخدم على عنصر مخطط زمني مقسّم على صفحات، سيظهر عنصر القائمة قراءة المزيد.

يقسّم Glass تلقائيًا عناصر المخطط الزمني التي يتم عرضها إلى صفحات text تشغيل 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 للمحتوى. التي تريد عرضها على كل بطاقة شاشة عرض محتوى كل منها علامة 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>

بشكل تلقائي، يتم عرض البطاقة الأولى لعنصر المخطط الزمني المقسّم على صفحات بطاقة غلاف وتظهر مرة أخرى عندما ينقر المستخدم على رمز مزيد من المعلومات عنصر قائمة. لمنع ظهور البطاقة الأولى من جديد بعد النقر على مزيد من المعلومات، يمكنك تحديد فئة CSS لـ 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 الأخرى للحصول على تحديث حذف عناصر المخطط الزمني

جارٍ الوصول إلى المرفقات

يمكنك الوصول إلى مرفقات أحد عناصر المخطط الزمني من خلال سمة مصفوفة باسم 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();

جارٍ إنشاء عناصر في القائمة

تتيح عناصر القائمة للمستخدمين طلب الإجراءات المتعلقة ببطاقة المخطط الزمني، وتأتي في نوعين: عناصر القائمة المضمنة وعناصر القائمة المخصصة.

توفر عناصر القائمة المضمنة الوصول إلى الوظائف الخاصة التي توفرها Google Glass، مثل قراءة بطاقة مخطط زمني بصوت عالٍ، أو الانتقال إلى الموقع الجغرافي أو مشاركة صورة أو الرد على رسالة:

تتيح عناصر القائمة المخصصة لتطبيقك الكشف عن سلوك محدد إلى Glassware، ويمكنك أيضًا توفير رمز عنصر قائمة ليتناسب مع الهوية البصرية للعلامة التجارية.

إضافة عناصر القائمة المضمنة

يمكنك إضافة عناصر القائمة المضمنة إلى عناصر المخطط الزمني عن طريق تعبئة menuItems array عند إدراجها. لاستخدام عنصر قائمة مدمج، ما عليك سوى ملء 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": "Hello world",
  "menuItems": [
    {
      "action": "REPLY"
    }
  ]
}

تحديد عناصر القائمة المخصصة

إذا لم تعمل عناصر القائمة المضمنة لديك، فيمكنك إنشاء عناصر قائمة مخصصة باستخدام الإجراءات الخاصة بك عن طريق القيام بما يلي عند إدراج أو تحديث عنصر مخطط زمني:

  • تحديد CUSTOM لـ menuItem.action.
  • حدِّد menuItem.id. وعندما ينقر المستخدمون على عنصر القائمة المخصص، يتم تطبيق Glassware تلقّي إشعار عبر تمّت تعبئة menuItem.id. وهذا يتيح لك تحديد مصدر .
  • حدِّد menuItem.values لإضافة iconUrl displayName الذي يظهر على Glass. الإشارة إلى ملف PNG بدقة 50 × 50 صورة بيضاء اللون مع خلفية شفافة لجهاز 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 الاشتراك في الإشعارات يتم إرسالها عندما يتخذ المستخدم إجراءات محددة على عنصر المخطط الزمني أو الوقت الذي يحدد فيه المستخدم الموقع تم تحديث. عند الاشتراك في إشعار، توفير عنوان URL لمعاودة الاتصال يعالج الإشعار.

تلقّي الإشعارات

يتم إرسال إشعار من 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)

يجب أن تستجيب الخدمة لواجهة برمجة التطبيقات باستخدام حالة HTTP 200 OK. الرمز في حالة عدم حدوث أي خطأ. في حال استجابة الخدمة برمز خطأ، قد تظهر في 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 على رقم تعريف الملف المحذوف. عنصر واحد. لم يعد العنصر يحتوي على بيانات وصفية بخلاف رقم تعريفه الموقع: 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، عيد ميلاد شيبوتل هو غدًا". تم إرسال الإشعار التالي إلى خدمات الويب الزجاجية:

{
  "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 لجهة الاتصال التي تمثّل تم استخدام الطلب الصوتي.