إنشاء تطبيق Android لـ Matter

1- مرحبًا

تم تصميم Matter لتحقيق هدف توحيد معايير إنترنت الأشياء (IoT)، وهو يربط الأجهزة المنزلية الذكية في مختلف الأنظمة البيئية، مثل Google Home وZigbee وBluetooth Mesh وZ-Wave وغير ذلك.

تُعد الأجهزة المحمولة نقطة تفاعل مركزية مع الأجهزة المنزلية الذكية. إذا أردت إنشاء تطبيقات Android خاصة بك لتتوافق مع أجهزة Matter، يمكننا مساعدتك في البدء بسرعة.

يعرض نموذج تطبيق Google Home المتوافق مع معيار Matter (GHSA for Matter) واجهات برمجة تطبيقات حزمة تطوير البرامج (SDK) للأجهزة الجوّالة للمنازل المنزلية، ما يتيح للمستخدمين تفويض الأجهزة ومشاركتها. يمكنك أيضًا استخدام نموذج التطبيق كأداة تعلُّم لفهم مفاهيم Matter الرئيسية بشكل أفضل، بالإضافة إلى أداة لتصحيح أخطاء التفاعلات مع أجهزة Matter وحلّها.

الإجراءات التي ستنفذّها

في هذا الدرس التطبيقي حول الترميز، ستنزّل رمز المصدر لنموذج التطبيق وتتعرّف على كيفية استخدام حزمة تطوير البرامج (SDK) للأجهزة الجوّالة للمنزل من أجل تكليف الأجهزة ومشاركتها. ستتعرّف أيضًا على كيفية استخدام مكتبات التفويض ومكتبات المجموعات من مكتبة المسألة القانونية (connectedhomeip).

بعد تنزيل نموذج التطبيق، سنراجع رمز المصدر في "استوديو Android" وسننفذ واجهات برمجة تطبيقات Home Mobile SDK API:

وستتعرّف أيضًا على مزيد من المعلومات حول مفاهيم إعداد التشغيل، والأقمشة المتوافقة مع معيار Matter، وكيفية التحكّم في أجهزة Matter.

المتطلبات

قبل البدء، تأكَّد من إكمال الخطوات التالية:

لست بحاجة إلى وحدة تحكُّم، مثل Google Nest Hub (الجيل الثاني)، لتشغيل الأجهزة والتحكّم فيها باستخدام نموذج التطبيق.

2- الإعداد

يمكنك العثور على تطبيق بدء استخدام الدرس التطبيقي حول الترميز في فرع "codelab". لبدء العمل باستخدام رمز مصدر الدرس التطبيقي حول الترميز، يمكنك تنزيل ملف ZIP.

ستستخدم ملف ZIP هذا codelab لإنشاء عينة عمل.

إصدارات الدرس التطبيقي حول الترميز

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

إذا كنت ترغب في استنساخ مستودع جيت هب، اتّبِع التعليمات الواردة في نموذج تطبيق README.

التبعيات

سنرشدك من خلال رمز المصدر المطلوب لمشاركة الأجهزة والعمولة عليها، ولكن قد يكون من المفيد التعرّف على التبعيات التالية قبل أن تبدأ. يُرجى العلم أنّه يتم الإعلان عن هذه التبعيات في الملف libs.versions.toml واستخدامها المحدّد في الملف build.gradle.kts.

رمز مصدر

سبق أن تم إنشاء واجهة المستخدم ومعظم الوظائف من أجلك.

في هذا الدرس التطبيقي حول الترميز، سنضيف وظيفة Matter إلى الملفات التالية:

  • java/commissioning/AppCommissioningService: يتيح لك تكليف الأجهزة بنسيج التطوير
  • java/screens/home/HomeScreen وjava/screens/home/HomeViewModel.kt: يتضمّنان وظيفة تفويض حزمة تطوير البرامج (SDK) للأجهزة الجوّالة في Home.
  • java/screens/device/DeviceScreen وjava/screens/device/DeviceViewModel: يتضمّنان طلبات Share Device API

يتم التعليق على كل ملف باستخدام كتلة التعليمات البرمجية التي ستعمل على تعديلها، على سبيل المثال:

// CODELAB: add commissioningFunction()

يسمح لك ذلك بتحديد القسم ذي الصلة بسرعة في الدرس التطبيقي حول الترميز.

3- العمولة إلى Google

قبل أن تتمكّن من التحكّم في الأجهزة والسماح لها بالاتصال ببعضها البعض من خلال النسيج نفسه، يجب أن يتم تفويضها من خلال أحد المفوّضين، وهو في هذه الحالة نموذج التطبيق هذا، Google Home Sample App for Matter.

من المهم معرفة المفاهيم التالية عن تفويض المسألة القانونية:

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

لتشغيل جهاز، يجب استخدام واجهة برمجة التطبيقات CommissioningClient API. تؤدي المكالمة إلى .commissionDevice() إلى عرض رسالة IntentSender التي تشغِّل النشاط المناسب في "خدمات Google Play":

interface CommissioningClient {
  Task<IntentSender> commissionDevice(CommissioningRequest request);
}

في الأقسام التالية، سنتطرق إلى الحد الأدنى من الرمز المطلوب لإسناد الأجهزة إلى قماش Google.

الخطوة 1: مشغّل الأنشطة

للتعامل مع IntentSender من CommissioningClient، يمكنك استخدام ActivityResultLauncher:

val commissioningLauncher = registerForActivityResult(
    StartIntentSenderForResult()
) { result: ActivityResult ->
    if (result.resultCode == RESULT_OK) {
        Timber.d(TAG, "Commissioning succeeded.")
    } else {
        Timber.d(TAG, "Commissioning failed. " + result.resultCode)
    }
}

الخطوة 2: وظيفة التشغيل

في ما يلي مثال أساسي يستخدم واجهة برمجة التطبيقات CommissioningClient API لتكليف جهاز بأقمشة Google.

  1. تبدأ عملية التكليف بالدالة commissionDevice(). أولاً، يتم تحديد CommissioningRequest. من خلال هذه الإعدادات التلقائية، يتم تكليف الأجهزة بطراز Android المحلي فقط.
  2. Matter هي نقطة دخول حزمة تطوير البرامج (SDK) للأجهزة الجوّالة في Home. في المكالمة التالية، يحصل .getCommissioningClient على CommissioningClient بحلول this (النشاط).
  3. يقبل .commissionDevice() CommissioningRequest.
  4. وأخيرًا، تم الاتصال بـ ".addOnSuccessListener" لمعالجة CommissioningResult وتشغيل نشاط جهاز العمولة لخدمات Google Play.
private fun commissionDevice() {
    val request: CommissioningRequest = CommissioningRequest.builder().build()
    Matter.getCommissioningClient(this)
        .commissionDevice(request)
        .addOnSuccessListener { result ->
            commissioningLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
}

يمكن الاستفادة من قماش Android المحلي عبر إعدادات Android لتبسيط عملية تكليف الأجهزة بأقمشة أخرى.

بعد ذلك، ستتعلم كيفية تكليف جهاز بنسيج تطوير.

لإلقاء نظرة عامة على واجهة المستخدم أثناء عملية التفويض، يمكنك الرجوع إلى نموذج تطبيق Google Home لمعيار Matter.

4. العمولة على نسيج التطوير

يمكن تصنيع الأجهزة بأكثر من قماش واحد. لإدارة عمليات الإقران الموثوق بها، تخزِّن الأجهزة FabricTable يتضمّن العديد من أعضاء FabricInfo، على سبيل المثال:

  • تحديد الأقمشة
  • معرّف العُقدة الذي عيَّنه القماش للجهاز
  • رقم تعريف المورّد
  • رقم تعريف النسيج
  • بيانات الاعتماد التشغيلية للجهاز

يقوم مدير المجال الإداري (ADM) بتعريف بيانات اعتماد القماش. في السيناريو السابق، تمثّل "خدمات Google Play" المنظومة المتكاملة التي تعمل كمرجع إصدار شهادات الجذر الموثوق به (CA). عند تكليف الأجهزة بنسيج Android المحلي، سيتضمن كل جهاز مجموعة بيانات اعتماد المجموعة نفسها ومجموعة مراجع التصديق نفسها.

خدمات المعالجة المخصّصة

لاعتماد بنية Android المحلية، استخدمنا المَعلمات التلقائية لإنشاء CommissioningRequest في CommissioningClient API:

val request: CommissioningRequest = CommissioningRequest.builder().build()

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

يمكنك إعلام Home Mobile SDK بأنّك تريد تكليف الأجهزة بنسيجك الخاص من خلال إرسال خدمة مخصّصة إلى CommissioningRequest:

class CommissioningRequest {
  static CommissioningRequest.Builder builder();

  class Builder {
    Builder setCommissioningService(@Nullable ComponentName commissioningService);

    CommissioningRequest build();
  }
}

في الخطوات التالية، سنُعدّل الدالة commissionDevice() لاستخدام خدمة مخصّصة. سنضيف أيضًا "مشغّل الأنشطة" إلى جزء "الصفحة الرئيسية" وسنستخدم كائنات LiveData لإدارة تدفق واجهة برمجة التطبيقات.

الخطوة 1: إنشاء مشغّل نشاط لنظام تحديد المواقع العالمي (GPS)

لنبدأ أولاً بإنشاء "مشغّل الأنشطة" للتعامل مع IntentSender من CommissioningClient API.

  1. افتح "HomeScreen" في مجلد "java/screens/home/".
  2. استبدل التعليق // CODELAB: commissionDeviceLauncher definition بالرمز التالي للتسجيل ومعالجة نتيجة نشاط التكليف:
    val commissionDeviceLauncher =
      rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartIntentSenderForResult()
      ) { result ->
        // Commission Device Step 5.
        // The Commission Device activity in GPS (step 4) has completed.
        val resultCode = result.resultCode
        if (resultCode == Activity.RESULT_OK) {
          Timber.d("CommissionDevice: Success")
          // We let the ViewModel know that GPS commissioning has completed successfully.
          // The ViewModel knows that we still need to capture the device name and will\
          // update UI state to trigger the NewDeviceAlertDialog.
          homeViewModel.gpsCommissioningDeviceSucceeded(result)
        } else {
          homeViewModel.commissionDeviceFailed(resultCode)
        }
      }
    

الخطوة 2: تشغيل إجراء الجهاز الذي يتطلب عمولة

في هذه الخطوة، يشغّل المستخدم الإجراء "جهاز العمولة" من خلال النقر على الزر "+" في أسفل يسار الشاشة الرئيسية. بعد ذلك، يتم إجراء مكالمة مع الرقم commissionDevice().

val onCommissionDevice = {
  ...
  commissionDevice(activity!!.applicationContext, commissionDeviceLauncher)
}

الخطوة 3: طلب بيانات من واجهة برمجة التطبيقات

  1. لا تزال في "HomeScreen.kt" في المجلد java/screens/home/.
  2. استبدل التعليق // CODELAB: commissionDevice بـ commissionDeviceRequest التالي. يربط setCommissioningService AppCommissioningService بمثيل CommissioningService، يتم عرضه في دالة رد اتصال. عند تمرير خدمة مخصّصة، ستعمل حزمة Home Mobile SDK أولاً على تكليف الأجهزة بأقمشة Android المحلية، ثم تُرسِل حمولة الإعداد مرة أخرى إلى AppCommissioningService.
    val commissionDeviceRequest =
        CommissioningRequest.builder()
            .setCommissioningService(ComponentName(
                context, AppCommissioningService::class.java))
            .build()
    
  3. اتصِل بالرقم .getCommissioningClient()، ثم اتصِل بـ .commissionDevice().
Matter.getCommissioningClient(context)
    .commissionDevice(commissionDeviceRequest)

لإكمال دالة commissionDevice، أضِف addOnSuccessListener وaddOnFailureListener:

    .addOnSuccessListener { result ->
      commissionDeviceLauncher.launch(IntentSenderRequest.Builder(result).build())
    }
    .addOnFailureListener { error ->
      Timber.e(error)
    }

5- إنشاء خدمة CommissioningService

في الدالة commissionDevice()، طلبنا الحصول على CommissioningService من واجهة برمجة التطبيقات CommissioningClient API. في هذا المسار، تعمل واجهة برمجة التطبيقات CommissioningClient API على تفويض الأجهزة بنموذج Android المحلي أولاً، ثم تعرض معاودة الاتصال التي تتضمن الكائن CommissioningRequestMetadata:

public interface CommissioningService {
interface Callback {
    void onCommissioningRequested(CommissioningRequestMetadata metadata);
  }
}

أمّا الآن، فعلينا أن نكتسب CommissioningService.Callback ونوفّر الوظائف المطلوبة لتشغيل الأجهزة في نموذج تطبيقنا. وفي ما يلي مثال على عملية تنفيذ CommissioningService أساسية:

class MatterCommissioningService : Service(), CommissioningService.Callback {
   private val commissioningServiceDelegate =
     CommissioningService.Builder(this)
       .setCallback(this)
       .build()

   override fun onBind(intent: Intent) = commissioningServiceDelegate.asBinder()

   override fun onCommissioningRequested(metadata: CommissioningRequestMetadata) {
     // perform commissioning

     commissioningServiceDelegate
       .sendCommissioningComplete(CommissioningCompleteMetadata.builder().build())
   }
 }

الخطوة 1: التعرّف على خدمة AppCommissioningService المخصَّصة

لمساعدتك في البدء، حدَّدنا من قبل بنية الفئة الأساسية للخدمة المخصّصة لشحن الطلبات. في ما يلي نظرة عامة سريعة على وظائف الخدمة. للمتابعة، افتح AppCommissioningService في java/commissioning.

لقد أضفنا عمليات الاستيراد التالية لواجهات برمجة تطبيقات Home Mobile SDK API:

import com.google.android.gms.home.matter.commissioning.CommissioningCompleteMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningRequestMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningService

تتضمن AppCommissioningService أيضًا مكتبات من مستودع المسألة القانونية (connectedhomeip):

import com.google.home_sample_app_for_matter.chip.ChipClient

وأخيرًا، تتضمّن الخدمة عمليات استيراد لدعم Hilt وKotlins.

بعد ذلك، ننشئ الدالة الإنشائية ونضبط بعض الإعدادات، بما فيها commissioningServiceDelegate، التي سنستخدمها لإعلام "خدمات Google Play" عند اكتمال عملية التكليف.

private lateinit var commissioningServiceDelegate: CommissioningService
...
commissioningServiceDelegate = CommissioningService.Builder(this).setCallback(this).build()

حان الوقت الآن لإضافة دوال التكليف.

الخطوة 2: إلغاء سياسة onCommissioning الخطوات المطلوبة

لتكليف الأجهزة ببناء بنية تطوير التطبيق، أكمل الخطوات التالية:

  1. فتح AppCommissioningService في java/commissioning.
  2. تحديد موقع الدالة onCommissioningRequested() تم تقديم رسالة سجلّ تطبع CommissioningRequestMetadata. استبدِل التعليق // CODELAB: onCommissioningRequested() لبدء تشغيل الكوروتين serviceScope والحصول على deviceId.
    // Perform commissioning on custom fabric for the sample app.
    serviceScope.launch {
      val deviceId = devicesRepository.incrementAndReturnLastDeviceId()
    
  3. تنفيذ التكليف: لتنفيذ هذه الخطوة، يمكننا ضبط معلومات الجهاز التي يعرضها الكائن CommissioningRequestMetadata. يستخدم ChipClient معلومات البيانات الوصفية هذه لإنشاء قناة آمنة بين تطبيق GHSA for Matter وجهازك.
    try {
      Timber.d(
          "Commissioning: App fabric -> ChipClient.establishPaseConnection(): deviceId [${deviceId}]")
      chipClient.awaitEstablishPaseConnection(
          deviceId,
          metadata.networkLocation.ipAddress.hostAddress!!,
          metadata.networkLocation.port,
          metadata.passcode)
      Timber.d(
          "Commissioning: App fabric -> ChipClient.commissionDevice(): deviceId [${deviceId}]")
      chipClient.awaitCommissionDevice(deviceId, null)
    } catch (e: Exception) {
      Timber.e(e, "onCommissioningRequested() failed")
      // No way to determine whether this was ATTESTATION_FAILED or DEVICE_UNREACHABLE.
      commissioningServiceDelegate
          .sendCommissioningError(CommissioningError.OTHER)
          .addOnSuccessListener {
            Timber.d(
                "Commissioning: commissioningServiceDelegate.sendCommissioningError() succeeded")
          }
          .addOnFailureListener { e2 ->
            Timber.e(e2, "Commissioning: commissioningServiceDelegate.sendCommissioningError() failed")
          }
      return@launch
    }
    
  4. استخدِم "commissioningServiceDelegate" لإعلام "خدمات Google Play" باكتمال عملية التكليف. في .sendCommissioningComplete()، أدخِل CommissioningCompleteMetadata.
    commissioningServiceDelegate
        .sendCommissioningComplete(
            CommissioningCompleteMetadata.builder().setToken(deviceId.toString()).build())
        .addOnSuccessListener {
          Timber.d("Commissioning: commissioningServiceDelegate.sendCommissioningComplete() succeeded")
        }
        .addOnFailureListener { e ->
          Timber.e(e, "Commissioning: commissioningServiceDelegate.sendCommissioningComplete() failed")
        }
    

تشغيل التطبيق

والآن بعد أن تم الانتهاء من وضع كل الرموز المطلوبة في تصنيع الأقمشة المحلية، حان الوقت لاختباره. اختَر جهاز Android وشغِّل التطبيق. من الشاشة الرئيسية، انقر على إضافة جهاز وأكمِل الخطوات اللازمة لإرسال الجهاز.

عند اكتمال التكليف، يشارك جهازك الآن في ألياف: ولكل قماش مجموعة خاصة به من بيانات الاعتماد ومعرّف قماش فريد 64 بت.

6. التحكّم في الأجهزة

يسمح لك التفويض بمواد التطوير باستخدام المكتبات من مستودع المسألة القانونية (connectedhomeip) للتحكّم في الأجهزة من خلال نموذج التطبيق.

لقد أنشأنا بعض الفئات المساعدة لتسهيل الوصول إلى المجموعات المُجمّعة للأجهزة وإرسال الأوامر. للاطّلاع على مزيد من المعلومات، افتح "ClustersHelper" في java/clusters. يستورد مساعد سينغلتون هذا المكتبات التالية للوصول إلى معلومات الجهاز:

import chip.devicecontroller.ChipClusters
import chip.devicecontroller.ChipStructs

يمكننا استخدام هذا الصف للحصول على مجموعة التفعيل/الإيقاف لأحد الأجهزة، ثم الاتصال بـ .toggle:

suspend fun toggleDeviceStateOnOffCluster(deviceId: Long, endpoint: Int) {
  Timber.d("toggleDeviceStateOnOffCluster())")
  val connectedDevicePtr =
      try {
        chipClient.getConnectedDevicePointer(deviceId)
      } catch (e: IllegalStateException) {
        Timber.e("Can't get connectedDevicePointer.")
        return
      }
  return suspendCoroutine { continuation ->
    getOnOffClusterForDevice(connectedDevicePtr, endpoint)
        .toggle(
            object : ChipClusters.DefaultClusterCallback {
              override fun onSuccess() {
                continuation.resume(Unit)
              }
              override fun onError(ex: Exception) {
                Timber.e("readOnOffAttribute command failure: $ex")
                continuation.resumeWithException(ex)
              }
            })
  }
}

إيقاف/تفعيل جهاز

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

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

يتم التحقّق من الحِزم على الجهاز وفك تشفيرها، ثم إرسالها من خلال معاودة الاتصال. تتضمّن وظائف معاودة الاتصال كلاً من EndpointId وClusterId وAttributeId التي يمكن الوصول إليها من attributePath. على سبيل المثال، يمكن تنفيذ هذا الرمز على جهاز Matter:

void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type,
                                       uint16_t size, uint8_t * value)
{
    // handle callback
    ClusterId clusterId     = attributePath.mClusterId;
    AttributeId attributeId = attributePath.mAttributeId;
}

في الخطوات التالية، عليك استخدام حزمة تطوير البرامج (SDK) لمعيار Matter وClustersHelper لتفعيل/إيقاف الجهاز.

  1. يمكنك الانتقال إلى DeviceViewModel في java/screens/device.
  2. تحديد موقع الدالة updateDeviceStateOn
  3. استبدِل التعليق // CODELAB: toggle برمز طلب clustersHelper، ثم حدِّث مستودع الأجهزة:
    Timber.d("Handling real device")
        try {
          clustersHelper.setOnOffDeviceStateOnOffCluster(deviceUiModel.device.deviceId, isOn, 1)
          devicesStateRepository.updateDeviceState(deviceUiModel.device.deviceId, true, isOn)
        } catch (e: Throwable) {
          Timber.e("Failed setting on/off state")
        }
    

يتم استدعاء هذه الدالة من DeviceScreen:

// On/Off Switch click.
val onOnOffClick: (value: Boolean) -> Unit = { value ->
  deviceViewModel.updateDeviceStateOn(deviceUiModel!!, value)
}

تشغيل التطبيق

شغِّل التطبيق لإعادة تحميل التحديثات. من الشاشة الرئيسية، بدِّل بين تشغيل جهازك وإيقافه.

7. مشاركة الأجهزة مع أنظمة بيئية أخرى

يُشار إلى مشاركة الجهاز باسم تدفق المشرفين المتعددين في مواصفات Matter.

في الخطوات السابقة، علِمنا أنّ حزمة Home Mobile SDK تتيح إمكانية تكليف الأجهزة بنسيج Android المحلي وأيضًا لأقمشة تطوير نموذج التطبيق. وهذا مثال على تدفق المشرفين المتعددين، حيث يمكن تفويض الأجهزة بأكثر من قماش واحد.

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

توفّر حزمة Home Mobile SDK هذه الوظيفة في ShareDeviceRequest API، ما يتيح لك ما يلي:

  1. افتح فترة العمولة المؤقتة للأجهزة.
  2. يمكنك تغيير حالة الأجهزة والسماح بتركيبها على نسيج آخر.
  3. يمكنك التحكّم في أجهزتك من خلال التطبيقات والمنظومات المتكاملة الأخرى.

في الخطوات التالية، ستستخدم حزمة تطوير البرامج (SDK) للأجهزة الجوّالة للمنزل من أجل مشاركة الأجهزة.

الخطوة 1: إنشاء مشغّل نشاط لنظام تحديد المواقع العالمي (GPS)

على غرار "مشغّل الأنشطة المستند إلى التكليف" الذي أنشأناه عند استخدام قماش في عملية التطوير، أنشأنا "مشغّل أنشطة الجهاز (Share Device Activity)" للتعامل مع واجهة برمجة التطبيقات IntentSender من واجهة برمجة التطبيقات CommissioningClient API.

  1. افتح "DeviceScreen" في مجلد "java/screens/device/".
  2. استبدل التعليق // CODELAB: shareDeviceLauncher definition بالرمز التالي لتسجيل نتيجة نشاط .shareDevice() والتعامل معها:
    val shareDeviceLauncher = rememberLauncherForActivityResult(
      contract = ActivityResultContracts.StartIntentSenderForResult()
    ) { result ->
      // Commission Device Step 5.
      // The Share Device activity in GPS (step 4) has completed.
      val resultCode = result.resultCode
      if (resultCode == Activity.RESULT_OK) {
        deviceViewModel.shareDeviceSucceeded()
      } else {
        deviceViewModel.shareDeviceFailed(resultCode)
      }
    }
    

الخطوة 2: تشغيل إجراء مشاركة الجهاز

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

// Share Device button click.
val onShareDevice: () -> Unit = {
 deviceViewModel.openPairingWindow(deviceUiModel!!.device.deviceId)
}

بعد فتح نافذة الاقتران بنجاح، تنقل "deviceViewModel" ذلك إلى واجهة المستخدم. يتم التواصل بين ViewModel وواجهة المستخدم من خلال عناصر StateFlow.

// Communicate to the UI that the pairing window is open.
// UI can then launch the GPS activity for device sharing.
_pairingWindowOpenForDeviceSharing.value = true

عند رؤية التغيير في كائن StateFlow، يُجري DeviceScreen الطلب التالي:

shareDevice(activity!!.applicationContext, shareDeviceLauncher, deviceViewModel)

الخطوة 3: طلب بيانات من واجهة برمجة التطبيقات

حان الوقت الآن لبدء مهمة مشاركة الجهاز.

  1. افتح "DeviceScreen.kt" في مجلد "java/screens/device/".
  2. تحديد موقع الدالة shareDevice() استبدل التعليق // CODELAB: shareDevice بـ ShareDeviceRequest. توفّر DeviceDescriptor معلومات محدّدة حول الجهاز، مثل "معرّف المورّد" و"معرّف المنتج" و"نوع الجهاز". في هذا المثال، نرمز إلى القيم بشكل ثابت.
    val shareDeviceRequest =
      ShareDeviceRequest.builder()
        .setDeviceDescriptor(DeviceDescriptor.builder().build())
        .setDeviceName("GHSAFM temp device name")
    
  3. اضبط CommissioningWindow والمَعلمات.
        .setCommissioningWindow(
            CommissioningWindow.builder()
                .setDiscriminator(Discriminator.forLongValue(DISCRIMINATOR))
                .setPasscode(SETUP_PIN_CODE)
                .setWindowOpenMillis(SystemClock.elapsedRealtime())
                .setDurationSeconds(OPEN_COMMISSIONING_WINDOW_DURATION_SECONDS.toLong())
                .build())
        .build()
    
  4. يمكنك طلب .getCommissioningClient()، هذه المرة فقط، استخدام .shareDevice() API.
    Matter.getCommissioningClient(context)
        .shareDevice(shareDeviceRequest)
    

من خلال معاودة الاتصال بنجاح لواجهة برمجة التطبيقات commissioningClient.shareDevice()، يمكن استخدام IntentSender لتشغيل ميزة "مشاركة نشاط الجهاز" في "خدمات Google Play".

  1. لإكمال دالة shareDevice، أضِف addOnSuccessListener وaddOnFailureListener. بعد إتمام العملية بنجاح، تم استدعاء "launch" في shareDeviceLauncher لتشغيل نشاط نظام تحديد المواقع العالمي (GPS) لمشاركة الجهاز.
        .addOnSuccessListener { result ->
          Timber.d("ShareDevice: Success getting the IntentSender: result [${result}]")
          shareDeviceLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
        .addOnFailureListener { error ->
          Timber.e(error)
          deviceViewModel.showMsgDialog("Share device failed", error.toString())
        }
    

تشغيل التطبيق

لمشاركة جهاز Matter مع منظومة متكاملة أخرى، يجب تثبيت نظام أساسي آخر على جهاز Android. لقد أنشأنا مثيلاً آخر من نموذج التطبيق الذي يمكنك استخدامه كمفوض مستهدف.

بعد تثبيت المفوَّض المستهدَف على جهاز Android، تأكَّد من إمكانية مشاركة جهاز Matter. يحمل تطبيق المفوّضين المستهدَفين تصنيف GHSAFM-TC.

يمكن لأجهزتك الآن المشاركة في ثلاثة أنواع من الأقمشة:

  1. بنية Android المحلية.
  2. بنية التطوير (هذا التطبيق).
  3. هذه القماش الثالث الذي شاركت الجهاز معه للتو.

8. الخطوات التالية

تهانينا

تهانينا، لقد أكملت هذا الدرس التطبيقي حول الترميز وتعرّفت على كيفية منح إذن الوصول إلى الأجهزة ومشاركتها باستخدام حزمة تطوير البرامج (SDK) للأجهزة الجوّالة في Home.

إذا كنت تواجه مشاكل في نموذج التطبيق، جرِّب إكمال الخطوات التالية للتحقّق من البيئة:

إذا كانت لديك أسئلة حول استخدام نموذج التطبيق أو اكتشاف خطأ في التعليمات البرمجية، يمكنك إرسال المشاكل إلى أداة تتبّع المشاكل في مستودع جيت هب:

للحصول على إرشادات رسمية من Google بشأن الأسئلة الفنية، يمكنك استخدام منتدى مطوّري "المنزل الذكي":

للحصول على دعم فني من المنتدى، استخدِم علامة google-smart-home على Stack Overflow: