یک برنامه اندروید برای Matter بسازید

۱. خوش آمدید

Matter که با هدف یکپارچه‌سازی استانداردهای اینترنت اشیا ساخته شده است، دستگاه‌های خانه هوشمند را در اکوسیستم‌های مختلف مانند Google Home، Zigbee، Bluetooth Mesh، Z-Wave و موارد دیگر به هم متصل می‌کند.

دستگاه‌های تلفن همراه نقطه تعامل اصلی با دستگاه‌های خانه هوشمند هستند. اگر می‌خواهید برنامه‌های اندروید خود را برای پشتیبانی از دستگاه‌های Matter بسازید، ما می‌توانیم به شما کمک کنیم تا سریع شروع کنید.

برنامه نمونه گوگل هوم برای Matter (GHSA for Matter) رابط‌های برنامه‌نویسی نرم‌افزار (API) کیت توسعه نرم‌افزار (SDK) هوم موبایل را به نمایش می‌گذارد و به کاربران امکان می‌دهد دستگاه‌ها را راه‌اندازی و به اشتراک بگذارند. همچنین می‌توانید از این برنامه نمونه به عنوان یک ابزار یادگیری برای درک بهتر مفاهیم کلیدی Matter و همچنین ابزاری برای اشکال‌زدایی و عیب‌یابی تعاملات با دستگاه‌های Matter استفاده کنید.

کاری که انجام خواهید داد

در این Codelab، شما کد منبع برنامه نمونه را دانلود خواهید کرد و یاد خواهید گرفت که چگونه از Home Mobile SDK برای راه‌اندازی و اشتراک‌گذاری دستگاه‌ها استفاده کنید. همچنین یاد خواهید گرفت که چگونه از کتابخانه‌های راه‌اندازی و خوشه‌ای از مخزن Matter ( connectedhomeip ) استفاده کنید.

بعد از دانلود برنامه نمونه، کد منبع را در اندروید استودیو بررسی کرده و APIهای Home Mobile SDK زیر را پیاده‌سازی خواهیم کرد:

همچنین در مورد مفاهیم راه‌اندازی، پارچه‌های Matter و نحوه کنترل دستگاه‌های Matter اطلاعات بیشتری کسب خواهید کرد.

آنچه نیاز دارید

قبل از شروع، حتماً مراحل زیر را انجام دهید:

برای راه‌اندازی و کنترل دستگاه‌ها با برنامه نمونه، به یک هاب، مثلاً یک هاب گوگل نست (نسل دوم)، نیازی ندارید.

۲. آماده شوید

برنامه‌ی آغازین codelab در شاخه‌ی codelab قرار دارد. برای شروع کار با کد منبع codelab، می‌توانید فایل ZIP را دانلود کنید.

شما از این فایل زیپ codelab برای ساخت یک نمونه‌ی کاربردی استفاده خواهید کرد.

نسخه‌های Codelab

شاخه codelab با نسخه ۲.۰.۰ برنامه نمونه برچسب‌گذاری شده است. برای مقایسه به‌روزرسانی‌های خود در حین انجام هر مرحله، می‌توانید کد منبع تکمیل‌شده برای این نسخه را دانلود کنید.

اگر می‌خواهید مخزن گیت‌هاب را کلون کنید، دستورالعمل‌های موجود در فایل README برنامه نمونه را دنبال کنید.

وابستگی‌ها

ما شما را در مورد کد منبع مورد نیاز برای اشتراک‌گذاری و راه‌اندازی دستگاه‌ها راهنمایی خواهیم کرد، اما ممکن است قبل از شروع، آگاهی از وابستگی‌های زیر مفید باشد. توجه داشته باشید که این وابستگی‌ها در فایل libs.versions.toml تعریف شده‌اند و نحوه‌ی استفاده از آنها در فایل build.gradle.kts مشخص شده است.

کد منبع

رابط کاربری و بیشتر قابلیت‌ها از قبل برای شما ایجاد شده‌اند.

برای این آزمایشگاه کد، قابلیت Matter را به فایل‌های زیر اضافه خواهیم کرد:

  • java/com/google/homesampleapp/commissioning/AppCommissioningService : به شما امکان می‌دهد دستگاه‌ها را به محیط توسعه متصل کنید.
  • java/com/google/homesampleapp/screens/home/HomeScreen و java/com/google/homesampleapp/screens/home/HomeViewModel.kt : شامل قابلیت راه‌اندازی Home Mobile SDK است.
  • java/com/google/homesampleapp/screens/device/DeviceScreen و java/com/google/homesampleapp/screens/device/DeviceViewModel : شامل فراخوانی‌های Share Device API می‌شود.

هر فایل با بلوک کدی که تغییر خواهید داد، کامنت‌گذاری شده است، برای مثال:

// CODELAB: add commissioningFunction()

این به شما امکان می‌دهد تا به سرعت بخش مربوطه را در codelab پیدا کنید.

۳. پورسانت به گوگل

قبل از اینکه بتوانید دستگاه‌ها را کنترل کنید و به آنها اجازه دهید در یک شبکه با یکدیگر ارتباط برقرار کنند، باید توسط یک کمیسیونر (Commissioner) راه‌اندازی شوند، که در این مورد، این برنامه نمونه، برنامه نمونه گوگل هوم برای Matter است.

درک مفاهیم زیر در مورد راه‌اندازی Matter مهم است:

  • پارچه‌ها به دستگاه‌ها اجازه می‌دهند تا با یکدیگر ارتباط برقرار کنند.
  • پارچه‌ها مجموعه‌ای مشترک از اعتبارنامه‌های منحصر به فرد را حفظ می‌کنند.
  • اکوسیستم‌ها مسئول صدور گواهی‌های ریشه معتبر، اختصاص شناسه‌های فابریک و اختصاص شناسه‌های گره منحصر به فرد هستند. یک اکوسیستم، سرویس بک‌اند یک کمیسر است، به عنوان مثال، Home Graph برای اکوسیستم Google Home.
  • دستگاه‌ها را می‌توان به بیش از یک Fabric (ویژگی چند مدیریتی) سفارش داد.

برای راه‌اندازی یک دستگاه، باید از API مربوط به CommissioningClient استفاده کنید. فراخوانی .commissionDevice() یک IntentSender برمی‌گرداند که activity مربوطه را در سرویس‌های گوگل پلی اجرا می‌کند:

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

در بخش‌های بعدی، به حداقل کد مورد نیاز برای اتصال دستگاه‌ها به Google fabric خواهیم پرداخت.

مرحله ۱: لانچر فعالیت

برای مدیریت 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)
    }
}

مرحله ۲: عملکرد راه‌اندازی

در اینجا یک مثال ساده آورده شده است که از API CommissioningClient برای اتصال یک دستگاه به Google fabric استفاده می‌کند.

  1. فرآیند راه‌اندازی با تابع commissionDevice() آغاز می‌شود. ابتدا، یک CommissioningRequest تعریف می‌شود. با این پیکربندی پیش‌فرض، دستگاه‌ها فقط به ساختار محلی اندروید (Local Android fabric) راه‌اندازی می‌شوند.
  2. Matter نقطه ورود برای Home Mobile SDK است. در فراخوانی بعدی، .getCommissioningClient توسط this (Activity) یک CommissioningClient دریافت می‌کند.
  3. .commissionDevice() CommissioningRequest را می‌پذیرد.
  4. و در نهایت، .addOnSuccessListener برای پردازش CommissioningResult و راه‌اندازی فعالیت دستگاه Commission Services Google Play (GPS) فراخوانی می‌شود.
private fun commissionDevice() {
    val request: CommissioningRequest = CommissioningRequest.builder().build()
    Matter.getCommissioningClient(this)
        .commissionDevice(request)
        .addOnSuccessListener { result ->
            commissioningLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
}

می‌توان از طریق تنظیمات اندروید، از Local Android Fabric برای ساده‌سازی فرآیند راه‌اندازی دستگاه‌های آن به سایر Fabricها استفاده کرد.

در مرحله بعد، یاد خواهید گرفت که چگونه یک دستگاه را به یک ساختار توسعه‌ای متصل کنید.

برای مرور کلی رابط کاربری در طول فرآیند راه‌اندازی، به راهنمای برنامه نمونه Google Home برای Matter مراجعه کنید.

۴. کمیسیون برای یک ساختار توسعه‌ای

دستگاه‌ها می‌توانند به بیش از یک Fabric متصل شوند. برای مدیریت جفت‌سازی‌های قابل اعتماد، دستگاه‌ها یک FabricTable حاوی اعضای مختلف FabricInfo ذخیره می‌کنند، به عنوان مثال:

  • شناسایی پارچه
  • شناسه گره (Node Id) که توسط fabric به دستگاه اختصاص داده شده است.
  • شناسه فروشنده
  • شناسه پارچه
  • اعتبارنامه‌های عملیاتی دستگاه

مدیر دامنه اداری (ADM) اعتبارنامه‌های فابریک را تعریف می‌کند. در سناریوی قبلی، سرویس‌های گوگل پلی اکوسیستمی است که به عنوان یک مرجع صدور گواهی ریشه (CA) مورد اعتماد عمل می‌کند. وقتی دستگاه‌ها را به فابریک محلی اندروید متصل می‌کنید، هر دستگاه شامل مجموعه یکسانی از اعتبارنامه‌های فابریک و مجموعه یکسانی از CAها می‌شود.

خدمات راه اندازی سفارشی

برای سفارش به ساختار محلی اندروید، از پارامترهای پیش‌فرض برای ساخت CommissioningRequest در CommissioningClient API استفاده کردیم:

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

اگر می‌خواهید دستگاه‌های جدید را از طریق برنامه خود کنترل و مدیریت کنید، باید یک ساختار توسعه محلی ایجاد کنید و اعتبارنامه‌های عملیاتی را برای راه‌اندازی دستگاه‌ها دریافت کنید. در این سناریو، برنامه شما به یک اکوسیستم منحصر به فرد و مستقل تبدیل می‌شود که اعتبارنامه‌های گره مناسب را به دستگاه‌ها اختصاص می‌دهد.

شما می‌توانید با ارسال یک سرویس سفارشی به CommissioningRequest، به Home Mobile SDK اطلاع دهید که می‌خواهید دستگاه‌ها را به فابریک خودتان سفارش دهید:

class CommissioningRequest {
  static CommissioningRequest.Builder builder();

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

    CommissioningRequest build();
  }
}

در مراحل بعدی، تابع commissionDevice() برای استفاده از یک سرویس سفارشی اصلاح خواهیم کرد. همچنین یک Activity Launcher به قطعه Home اضافه خواهیم کرد و از اشیاء LiveData برای مدیریت جریان API استفاده خواهیم کرد.

مرحله ۱: یک لانچر فعالیت GPS ایجاد کنید

ابتدا، بیایید یک Activity Launcher برای مدیریت IntentSender از CommissioningClient API ایجاد کنیم.

  1. فایل HomeScreen در پوشه java/com/google/homesampleapp/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)
        }
      }
    

مرحله ۲: فعال کردن دستگاه کمیسیون

در این مرحله، کاربر با کلیک بر روی دکمه "+" در پایین سمت راست صفحه اصلی، عملکرد "دستگاه کمیسیون" را فعال می‌کند. سپس فراخوانی به commissionDevice() انجام می‌شود.

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

مرحله ۳: فراخوانی API

  1. هنوز در فایل HomeScreen.kt در پوشه java/com/google/homesampleapp/screens/home قرار دارد.
  2. کامنت // CODELAB: commissionDevice را با commissionDeviceRequest زیر جایگزین کنید. setCommissioningService AppCommissioningService را به یک نمونه CommissioningService متصل می‌کند که در یک تابع فراخوانی برگردانده می‌شود. وقتی یک سرویس سفارشی ارسال می‌کنید، Home Mobile SDK ابتدا دستگاه‌ها را به ساختار محلی اندروید متصل می‌کند، سپس payload مربوط به onboarding را به 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)
    }

۵. یک سرویس راه‌اندازی ایجاد کنید

در تابع commissionDevice() ، ما درخواست دریافت یک CommissioningService از CommissioningClient API را دادیم. در این جریان، CommissioningClient API ابتدا دستگاه‌ها را به ساختار محلی اندروید (Local Android fabric) سفارش می‌دهد، سپس یک callback را برمی‌گرداند که شامل شیء 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())
   }
 }

مرحله ۱: بررسی AppCommissioningService سفارشی

برای کمک به شما در شروع کار، ما قبلاً ساختار کلاس پایه را برای CommissioningService سفارشی خود تعریف کرده‌ایم. در اینجا مروری سریع بر عملکرد سرویس ارائه شده است. برای ادامه، AppCommissioningService در java/commissioning باز کنید.

ما ایمپورت‌های زیر را برای APIهای SDK مربوط به Home Mobile اضافه کرده‌ایم:

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 همچنین شامل کتابخانه‌هایی از مخزن Matter ( connectedhomeip ) است:

import com.google.homesampleapp.chip.ChipClient

در نهایت، این سرویس شامل ایمپورت‌هایی برای پشتیبانی از کوروتین‌های Hilt و Kotlin است.

در مرحله بعد، سازنده را ایجاد می‌کنیم و چند مورد را تنظیم می‌کنیم، از جمله commissioningServiceDelegate که از آن برای اطلاع‌رسانی به سرویس‌های Google Play هنگام تکمیل راه‌اندازی استفاده خواهیم کرد.

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

حالا وقت اضافه کردن توابع راه‌اندازی است.

مرحله 2: لغو درخواست راه‌اندازی

برای اتصال دستگاه‌ها به محیط توسعه‌ی برنامه، مراحل زیر را انجام دهید:

  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 برای اطلاع‌رسانی به سرویس‌های گوگل پلی مبنی بر تکمیل فرآیند راه‌اندازی استفاده کنید. در .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")
        }
    }
    

برنامه را اجرا کنید

اکنون که تمام کدهای مورد نیاز برای راه‌اندازی در محیط محلی ما آماده شده‌اند، زمان آزمایش آن فرا رسیده است. دستگاه اندروید خود را انتخاب کنید و برنامه را اجرا کنید. از صفحه اصلی، روی افزودن دستگاه ضربه بزنید و مراحل راه‌اندازی دستگاه خود را تکمیل کنید.

وقتی راه‌اندازی کامل شد، دستگاه شما اکنون در دو ساختار شرکت می‌کند: ساختار محلی اندروید و ساختار توسعه محلی شما. هر ساختار مجموعه‌ای از اعتبارنامه‌ها و یک شناسه ساختاری ۶۴ بیتی منحصر به فرد دارد.

۶. دستگاه‌های کنترل

راه‌اندازی یک ساختار توسعه به شما این امکان را می‌دهد که از کتابخانه‌های موجود در مخزن Matter ( connectedhomeip ) برای کنترل دستگاه‌ها از طریق برنامه نمونه استفاده کنید.

ما چند کلاس کمکی ایجاد کرده‌ایم تا دسترسی به کلاسترهای دستگاه و ارسال دستورات را آسان‌تر کنیم. برای کسب اطلاعات بیشتر، ClustersHelper در java/clusters باز کنید. این کلاس کمکی Singleton کتابخانه‌های زیر را برای دسترسی به اطلاعات دستگاه وارد می‌کند:

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

تغییر وضعیت یک دستگاه

پس از اینکه یک دستگاه را راه‌اندازی کردید، payload برگردانده شده در 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;
}

در مراحل بعدی، از Matter SDK و 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)
}

برنامه را اجرا کنید

برنامه را اجرا کنید تا به‌روزرسانی‌هایتان دوباره بارگذاری شوند. از صفحه اصلی، دستگاه خود را روشن و خاموش کنید.

۷. دستگاه‌ها را با سایر اکوسیستم‌ها به اشتراک بگذارید

در مشخصات Matter، به اشتراک‌گذاری یک دستگاه، جریان چند-مدیره گفته می‌شود.

در مراحل قبلی، آموختیم که Home Mobile SDK امکان اتصال دستگاه‌ها به Local Android fabric و همچنین به یک fabric توسعه برای برنامه نمونه را فراهم می‌کند. این نمونه‌ای از جریان چند ادمینی است که در آن دستگاه‌ها می‌توانند به بیش از یک fabric متصل شوند.

حال، ممکن است بخواهید دستگاه‌ها را با پارچه‌های بیشتری به اشتراک بگذارید، به خصوص اگر این خانه‌ای باشد که افراد در مورد برنامه‌ها و پلتفرم‌ها ترجیحات خاص خود را دارند.

کیت توسعه نرم‌افزار Home Mobile این قابلیت را در API مربوط به ShareDeviceRequest ارائه می‌دهد و به شما امکان می‌دهد:

  1. یک پنجره راه‌اندازی موقت برای دستگاه‌ها باز کنید.
  2. وضعیت دستگاه‌های خود را تغییر دهید و آنها را قادر سازید تا به یک ساختار دیگر متصل شوند.
  3. دستگاه‌های خود را از برنامه‌ها و اکوسیستم‌های دیگر کنترل کنید.

در مراحل بعدی، از Home Mobile SDK برای اشتراک‌گذاری دستگاه‌ها استفاده خواهید کرد.

مرحله ۱: یک لانچر فعالیت GPS ایجاد کنید

مشابه لانچر فعالیت راه‌اندازی که هنگام سفارش به یک ساختار توسعه ایجاد کردیم، یک لانچر فعالیت دستگاه اشتراکی نیز ایجاد کرده‌ایم تا IntentSender از API کمیسیون کلاینت مدیریت کند.

  1. DeviceScreen در پوشه java/com/google/homesampleapp/screens/device/ باز کنید.
  2. برای ثبت و مدیریت نتیجه‌ی اکتیویتی .shareDevice() ‎، کد زیر را جایگزین کامنت // CODELAB: shareDeviceLauncher definition ‎ کنید:
    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)
      }
    }
    

مرحله ۲: فعال کردن عملکرد اشتراک‌گذاری دستگاه

در این مرحله، کاربر با کلیک بر روی دکمه‌ی «اشتراک‌گذاری» روی صفحه‌ی دستگاه، اقدام به فعال‌سازی «اشتراک‌گذاری دستگاه» می‌کند. سپس یک فراخوانی به deviceViewModel انجام می‌شود تا یک پنجره‌ی جفت‌سازی برای اشتراک‌گذاری دستگاه باز شود.

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

پس از باز شدن موفقیت‌آمیز پنجره‌ی paring، deviceViewModel این حقیقت را به UI اطلاع می‌دهد. ارتباط بین ViewModel و UI از طریق اشیاء 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)

مرحله ۳: فراخوانی API

اکنون زمان آن رسیده است که یک وظیفه اشتراک‌گذاری دستگاه را آغاز کنیم.

  1. DeviceScreen.kt در پوشه java/com/google/homesampleapp/screens/device/ باز کنید.
  2. تابع shareDevice() را پیدا کنید. عبارت // CODELAB: shareDevice با ShareDeviceRequest جایگزین کنید. DeviceDescriptor اطلاعات خاصی در مورد دستگاه مانند شناسه فروشنده، شناسه محصول و نوع دستگاه ارائه می‌دهد. در این مثال، مقادیر را به صورت hard-code وارد کرده‌ایم.
    val shareDeviceRequest =
      ShareDeviceRequest.builder()
        .setDeviceDescriptor(DeviceDescriptor.builder().build())
        .setDeviceName("GHSAFM temp device name")
    
  3. پنجره‌ی راه‌اندازی و پارامترها را تنظیم کنید.
        .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() ، فقط این بار، از API .shareDevice() استفاده کنید.
    Matter.getCommissioningClient(context)
        .shareDevice(shareDeviceRequest)
    

فراخوانی موفقیت‌آمیز تابع commissioningClient.shareDevice() ، IntentSender را برای راه‌اندازی اکتیویتی Share Device در سرویس‌های گوگل پلی فراهم می‌کند.

  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 خود با سایر اکوسیستم‌ها، باید پلتفرم دیگری را روی دستگاه اندروید خود نصب کنید. ما نمونه دیگری از برنامه نمونه را ایجاد کرده‌ایم که می‌توانید از آن به عنوان کمیسر هدف استفاده کنید.

پس از نصب برنامه‌ی Target Commissioner روی دستگاه اندروید خود، مطمئن شوید که می‌توانید دستگاه Matter خود را به اشتراک بگذارید. برنامه‌ی Target Commissioner با نام GHSAFM-TC شناخته می‌شود.

دستگاه‌های شما اکنون می‌توانند در سه پارچه شرکت کنند:

  1. ساختار اندروید محلی.
  2. بستر توسعه شما (این برنامه).
  3. این پارچه سومی که الان دستگاه را با آن به اشتراک گذاشتید.

۸. مراحل بعدی

تبریک می‌گویم

تبریک می‌گویم، شما این Codelab را با موفقیت به پایان رساندید و یاد گرفتید که چگونه دستگاه‌ها را با استفاده از Home Mobile SDK راه‌اندازی و به اشتراک بگذارید.

اگر با برنامه نمونه مشکل دارید، مراحل تأیید محیط خود را انجام دهید:

اگر در مورد استفاده از برنامه نمونه سؤالی دارید یا اشکالی در کد کشف کرده‌اید، می‌توانید مشکلات را به Issue Tracker در مخزن GitHub ارسال کنید:

برای دریافت راهنمایی رسمی از گوگل در مورد سوالات فنی، از انجمن توسعه‌دهندگان خانه هوشمند استفاده کنید:

برای دریافت پشتیبانی فنی از انجمن، از برچسب google-smart-home در Stack Overflow استفاده کنید: