عرض التحديثات الدورية في المربّعات

أنشئ مربّعات تتضمّن محتوى يتغيّر بمرور الوقت.

العمل مع المخططات الزمنية

يتألف المخطط الزمني من مثيل واحد أو أكثر TimelineEntry يحتوي كلّ منها على تنسيق يتم عرضه خلال فاصل زمني معيّن. يجب أن تتضمّن كل مربّعات معلومات مخططًا زمنيًا.

مخطّط بياني للمخطط الزمني للمربّع

مربّعات الإدخال الواحد

في كثير من الأحيان، يمكن وصف مربّع باستخدام TimelineEntry واحد. يكون التنسيق ثابتًا، ولا تتغيّر سوى المعلومات داخل التنسيق. على سبيل المثال، يعرض مربّع الشاشة الذي يعرض مستوى لياقتك البدنية خلال اليوم دائمًا تنسيق مستوى التقدّم نفسه، ولكن يمكنك تعديل هذا التنسيق لعرض قيم مختلفة. في هذه الحالات، لا يمكنك معرفة متى قد يتغيّر المحتوى مسبقًا.

اطّلِع على المثال التالي لمربّع يتضمّن TimelineEntry واحدًا:

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
    val tile =
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            // We add a single timeline entry when our layout is fixed, and
            // we don't know in advance when its contents might change.
            .setTileTimeline(Timeline.fromLayoutElement(simpleLayout(this)))
            .build()
    return Futures.immediateFuture(tile)
}

إدخالات المخطط الزمني ذات الصلة بوقت معيّن

يمكن أن يحدِّد TimelineEntry بشكل اختياري فترة صلاحية، ما يسمح للقرص المميّز بتغيير تنسيقه في وقت محدّد بدون الحاجة إلى أن يُرسِل التطبيق قرصًا جديدًا.

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

تسمح واجهة برمجة التطبيقات Tiles API بتداخل فترات الصلاحية، حيث تكون الشاشة التي تتضمن أقصر فترة زمنية متبقية هي الشاشة المعروضة. يتم عرض حدث واحد فقط في كل مرة.

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

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
    val timeline = Timeline.Builder()

    // Add fallback "no meetings" entry
    // Use the version of TimelineEntry that's in androidx.wear.protolayout.
    timeline.addTimelineEntry(
        TimelineBuilders.TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build()
    )

    // Retrieve a list of scheduled meetings
    val meetings = MeetingsRepo.getMeetings()
    // Add a timeline entry for each meeting
    meetings.forEach { meeting ->
        timeline.addTimelineEntry(
            TimelineBuilders.TimelineEntry.Builder()
                .setLayout(getMeetingLayout(meeting))
                .setValidity(
                    // The tile should disappear when the meeting begins
                    // Use the version of TimeInterval that's in
                    // androidx.wear.protolayout.
                    TimelineBuilders.TimeInterval.Builder()
                        .setEndMillis(meeting.dateTimeMillis)
                        .build()
                )
                .build()
        )
    }

    val tile =
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setTileTimeline(timeline.build())
            .build()
    return Futures.immediateFuture(tile)
}

إعادة تحميل مربّع

قد تنتهي صلاحية المعلومات المعروضة على مربّع معلومات بعد مرور بعض الوقت. على سبيل المثال، فإنّ مربّع الطقس الذي يعرض درجة الحرارة نفسها على مدار اليوم ليس دقيقًا.

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

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> =
    Futures.immediateFuture(
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
            .setTileTimeline(Timeline.fromLayoutElement(getWeatherLayout()))
            .build()
    )

عند ضبط فاصل حداثة، يستدعي النظام onTileRequest() بعد انتهاء الفاصل بوقت قصير. في حال عدم ضبط فاصل حداثة، لن يُطلِق النظام طلبًا إلى onTileRequest().

يمكن أن تنتهي صلاحية مربّع معلومات أيضًا بسبب حدث خارجي. على سبيل المثال، قد يزيل مستخدم اجتماعًا من تقويمه، وإذا لم يتم إعادة تحميل المربّع، سيظل المربّع يعرض الاجتماع المحذوف. في هذه الحالة، يمكنك طلب إعادة تحميل من أي موضع في رمز تطبيقك، كما هو موضّح في نموذج الرمز البرمجي التالي:

Kotlin

fun eventDeletedCallback() {
     TileService.getUpdater(context)
             .requestUpdate(MyTileService::class.java)
}

Java

public void eventDeletedCallback() {
   TileService.getUpdater(context)
           .requestUpdate(MyTileService.class);
}

اختيار سير عمل التعديل

اتّبِع أفضل الممارسات التالية لتحديد كيفية ضبط تحديثات مربّعات المعلومات:

  • إذا كان التعديل متوقّعًا، على سبيل المثال، إذا كان للحدث التالي في تقويم المستخدم، استخدِم مخططًا زمنيًا.
  • عند جلب بيانات المنصة، استخدِم ربط البيانات لكي يعدّل النظام البيانات تلقائيًا.
  • إذا كان بالإمكان احتساب التعديل على الجهاز في وقت قصير، مثل تعديل موضع صورة في مربّع شروق الشمس، استخدِم onTileRequest().

    ويُعدّ هذا الإجراء مفيدًا بشكل خاص عندما تحتاج إلى إنشاء كل الصور مسبقًا. إذا كنت بحاجة إلى إنشاء صورة جديدة في وقت لاحق، يُرجى الاتصال بالرقم setFreshnessIntervalMillis().

  • إذا كنت تُجري عملًا مكثّفًا في الخلفية بشكل متكرّر، مثل فحص بيانات الطقس، استخدِم WorkManager وأرسِل التعديلات إلى مربّع الرموز.

  • إذا كان التعديل استجابةً لحدث خارجي، مثل إشعال المصابيح أو تلقّي رسالة إلكترونية أو تعديل ملاحظة، أرسِل رسالة المراسلة عبر السحابة الإلكترونية من Firebase (FCM) لتنشيط تطبيقك مرة أخرى، ثم أرسِل التعديلات إلى مربّع المعلومات.

  • إذا كانت عملية مزامنة بيانات المربّعات قد تكون باهظة التكلفة، عليك اتّباع الخطوات التالية:

    1. حدِّد موعدًا لمزامنة البيانات.
    2. ابدأ موقّتًا لمدة ثانية أو ثانيتَين.
    3. إذا تلقّيت تعديلاً من مصدر بيانات عن بُعد قبل انتهاء الوقت، أظهِر القيمة المعدَّلة من مزامنة البيانات. بخلاف ذلك، أظهِر قيمة محلية مخزّنة مؤقتًا.