1. مرحبًا
تم تصميم معيار Matter بهدف توحيد معايير إنترنت الأشياء، وهو يربط الأجهزة المنزلية الذكية في مختلف الأنظمة المتوافقة، مثل Google Home وZigbee وBluetooth Mesh وZ-Wave وغيرها.
تُعد الأجهزة الجوّالة نقطة تفاعل مركزية مع الأجهزة المنزلية الذكية. إذا أردت إنشاء تطبيقات Android خاصة بك لتتوافق مع أجهزة Matter، يمكننا مساعدتك في البدء بسرعة.
يعرض تطبيق Google Home التجريبي لبروتوكول Matter (GHSA for Matter) واجهات برمجة التطبيقات Home Mobile SDK، ما يتيح للمستخدمين إعداد الأجهزة ومشاركتها. يمكنك أيضًا استخدام نموذج التطبيق كأداة تعليمية لفهم مفاهيم Matter الأساسية بشكل أفضل، بالإضافة إلى أداة لتصحيح الأخطاء وتحديد المشاكل وحلّها في التفاعلات مع أجهزة Matter.
الإجراءات التي ستنفذّها
في هذا الدرس التطبيقي حول الترميز، ستنزّل الرمز المصدر لنموذج التطبيق وتتعرّف على كيفية استخدام حزمة تطوير البرامج (SDK) للأجهزة الجوّالة في Home لإعداد الأجهزة ومشاركتها. يمكنك أيضًا التعرّف على كيفية استخدام مكتبات التفويض والتجميع من مستودع Matter (connectedhomeip).
بعد تنزيل التطبيق النموذجي، سنراجع رمز المصدر في "استوديو Android" وننفّذ واجهات برمجة التطبيقات التالية لحزمة Home Mobile SDK:
ستتعرّف أيضًا على المزيد من المعلومات حول مفاهيم الإعداد، وشبكات Matter، وكيفية التحكّم في أجهزة Matter.
المتطلبات
قبل البدء، تأكَّد من إكمال الخطوات التالية:
- راجِع دليل تطبيق Google Home التجريبي المتوافق مع Matter.
- تنزيل "استوديو Android"
- يجب أن يتوفّر لديك جهاز يعمل بالإصدار Android O (الإصدار 8.1، المستوى 27 من واجهة برمجة التطبيقات) أو إصدار أحدث لإجراء الاختبار. للتأكّد من أنّ جهازك يتوافق مع أحدث إصدار من Matter، راجِع دليل التحقّق من وحدات Matter وخدماتها.
- استخدام جهاز متوافق مع معيار Matter ويتضمّن إمكانات التشغيل والإيقاف للحدّ من مشاكل البيئة، ننصحك بشدة باستخدام جهاز Matter الظاهري (MVD) في البداية. إذا واجهت أي مشاكل، سيكون من الأسهل بكثير التحقيق فيها إذا تم استخدام نموذج التطبيق مع MVD. في ما يلي بعض الخيارات الأخرى:
- أنشئ جهازًا افتراضيًا متوافقًا مع Matter باستخدام تطبيق
rootnode_dimmablelight_bCwGYSDpoe. عند إنشاء عملية دمج مع Matter في Play Console، استخدِم0xFFF1كمعرّف المورّد و0x8000كمعرّف المنتج. - إنشاء جهاز Espressif باستخدام
all-clusters-appعند إنشاء عملية دمج Matter في Play Console، استخدِم0xFFF1كمعرّف المورّد و0x8001كمعرّف المنتج.
- أنشئ جهازًا افتراضيًا متوافقًا مع Matter باستخدام تطبيق
- راجِع كيفية إعداد "خدمات Google Play".
لا تحتاج إلى مركز تحكّم، مثل Google Nest Hub (الجيل الثاني)، لتشغيل الأجهزة والتحكّم فيها باستخدام نموذج التطبيق.
2. طريقة الإعداد
يتوفّر تطبيق البداية الخاص بدرس البرمجة العملي في الفرع codelab. لبدء العمل مع الرمز المصدري لبرنامج codelab، يمكنك تنزيل ملف ZIP.
ستستخدم codelab ملف ZIP هذا لإنشاء نموذج عملي.
إصدارات الدروس التطبيقية حول الترميز
تم وضع علامة codelab على فرع الإصدار 2.0.0 من نموذج التطبيق. ولمقارنة التعديلات أثناء تنفيذ كل خطوة، يمكنك تنزيل الرمز المصدر المكتمل لهذا الإصدار.
إذا أردت استنساخ مستودع GitHub، اتّبِع التعليمات الواردة في ملف README الخاص بنموذج التطبيق.
الاعتمادية
سنقدّم لك الإرشادات بشأن رمز المصدر المطلوب لمشاركة الأجهزة وتوفيرها، ولكن قد يكون من المفيد معرفة التبعيات التالية قبل البدء. يُرجى العِلم أنّه يتم تحديد هذه التبعيات في الملف libs.versions.toml وتحديد استخدامها في الملف build.gradle.kts.
- Home Mobile SDK
- مكتبات Matter SDK
- Jetpack Compose تم تنفيذ واجهة المستخدم بالكامل باستخدام Compose.
- التصميم المتعدد الأبعاد لمزيد من المعلومات، يمكنك الاطّلاع على MDC-103 Android: تخصيص التصميم المتعدد الأبعاد باستخدام اللون والارتفاع والنوع (Kotlin) وأداة إنشاء المظاهر المستندة إلى Material Design.
- Proto DataStore، تُستخدَم للحفاظ على بيانات التطبيق. يتم تخزين مستودعات مخزن البيانات وأدوات التسلسل في
java/data، بما في ذلك المخططات الخاصة بالأجهزة والإعدادات المفضَّلة للمستخدم. لمزيد من المعلومات حول DataStore، يُرجى الرجوع إلى العمل مع Proto DataStore. - Hilt لتخزين البيانات مؤقتًا وإتاحة إمكانية إدخال التبعيات
رمز مصدر
تمّ إنشاء واجهة المستخدم ومعظم الوظائف لك مسبقًا.
في هذا الدرس التطبيقي حول الترميز، سنضيف وظائف 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()
يتيح لك ذلك تحديد موقع القسم المناسب في الدرس العملي بسرعة.
3- العمولة المدفوعة إلى Google
قبل أن تتمكّن من التحكّم في الأجهزة والسماح لها بالتواصل مع بعضها البعض ضمن النسيج نفسه، يجب أن يتم إعدادها من قِبل "المُعدّ"، وهو في هذه الحالة هذا التطبيق النموذجي، أي تطبيق Google Home النموذجي المتوافق مع Matter.
من المهم فهم المفاهيم التالية حول عملية إعداد Matter:
- تسمح الأقمشة للأجهزة بالتواصل مع بعضها البعض.
- تحتفظ الأقمشة بمجموعة مشتركة من بيانات الاعتماد الفريدة.
- تكون الأنظمة المتكاملة مسؤولة عن إصدار شهادات الجذر الموثوقة وتحديد معرّفات البنية الأساسية وتحديد معرّفات العُقد الفريدة. النظام الأساسي هو خدمة الخلفية الخاصة بالجهة المسؤولة عن الإعداد، مثل "رسم بياني للمنزل" لنظام Google Home الأساسي.
- يمكن إعداد الأجهزة لأكثر من شبكة واحدة (ميزة "المشرفون المتعدّدون").
لتفعيل جهاز، عليك استخدام CommissioningClient API. يؤدي طلب إلى .commissionDevice() إلى عرض IntentSender، ما يؤدي إلى تشغيل النشاط المناسب في "خدمات Google Play":
interface CommissioningClient {
Task<IntentSender> commissionDevice(CommissioningRequest request);
}
في الأقسام التالية، سنتناول الحد الأدنى من الرموز المطلوبة لتفعيل الأجهزة على منصة Google.
الخطوة 1: Activity Launcher
للتعامل مع 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.
- تبدأ عملية الإعداد باستخدام الدالة
commissionDevice(). أولاً، يتم تحديدCommissioningRequest. باستخدام هذا الإعداد التلقائي، يتم إعداد الأجهزة في شبكة Android المحلية فقط. -
Matterهي نقطة الدخول إلى حزمة تطوير البرامج (SDK) للأجهزة الجوّالة الخاصة بتطبيق "Google Home". في المكالمة التالية، يحصل.getCommissioningClientعلى CommissioningClient من خلالthis(Activity). - يقبل
.commissionDevice()CommissioningRequest. - وأخيرًا، يتم استدعاء
.addOnSuccessListenerلمعالجةCommissioningResultوتشغيل نشاط Commission Device في "خدمات 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 من خلال إعدادات Android لتبسيط عملية ربط أجهزتها بشبكات أخرى.
بعد ذلك، ستتعرّف على كيفية إعداد جهاز في بيئة تطوير.
للحصول على نظرة عامة على واجهة المستخدم أثناء عملية الإعداد، يُرجى الرجوع إلى دليل تطبيق Google Home التجريبي لـ Matter.
4. العمولة إلى نسيج التطوير
يمكن إعداد الأجهزة لأكثر من شبكة منزلية واحدة. لإدارة عمليات الاقتران الموثوق بها، تخزِّن الأجهزة FabricTable يحتوي على عناصر FabricInfo مختلفة، مثل:
- تحديد نوع القماش
- رقم تعريف العقدة الذي خصّصته البنية للجهاز
- معرّف المورّد
- معرّف القماش
- بيانات اعتماد تشغيل الجهاز
يحدد مدير النطاق الإداري (ADM) بيانات اعتماد البنية الأساسية. في السيناريو السابق، تكون "خدمات Google Play" هي المنظومة المتكاملة التي تعمل كمرجع تصديق جذر (CA) موثوق به. عند إعداد الأجهزة في Local Android fabric، يتضمّن كل جهاز مجموعة بيانات اعتماد fabric نفسها، ومجموعة شهادات CA نفسها.
خدمات التشغيل المخصّصة
لإرسال طلب إلى Local Android fabric، استخدَمنا المَعلمات التلقائية لإنشاء CommissioningRequest في CommissioningClient API:
val request: CommissioningRequest = CommissioningRequest.builder().build()
إذا أردت التحكّم في الأجهزة الجديدة وإدارتها من تطبيقك، عليك إنشاء بنية تطوير محلية والحصول على بيانات الاعتماد التشغيلية لتفعيل الأجهزة. في هذه الحالة، يصبح تطبيقك نظامًا بيئيًا فريدًا ومستقلاً يمنح الأجهزة بيانات اعتماد العُقد المناسبة.
يمكنك إبلاغ حزمة تطوير البرامج (SDK) لتطبيق "Google Home" للأجهزة الجوّالة بأنّك تريد إعداد الأجهزة في شبكتك الخاصة من خلال تمرير خدمة مخصّصة إلى CommissioningRequest:
class CommissioningRequest {
static CommissioningRequest.Builder builder();
class Builder {
Builder setCommissioningService(@Nullable ComponentName commissioningService);
CommissioningRequest build();
}
}
في الخطوات التالية، سنعدّل الدالة commissionDevice() لاستخدام خدمة مخصّصة. سنضيف أيضًا "مشغّل الأنشطة" إلى جزء "الصفحة الرئيسية"، وسنستخدم عناصر LiveData لإدارة مسار واجهة برمجة التطبيقات.
الخطوة 1: إنشاء مشغّل لنشاط نظام تحديد المواقع العالمي (GPS)
أولاً، لننشئ Activity Launcher لمعالجة IntentSender من CommissioningClient API.
- افتح
HomeScreenفي المجلدjava/com/google/homesampleapp/screens/home/. - استبدِل التعليق
// 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: استدعاء واجهة برمجة التطبيقات
- لا يزال في
HomeScreen.ktفي المجلدjava/com/google/homesampleapp/screens/home - استبدِل التعليق
// CODELAB: commissionDeviceبالتعليق التاليcommissionDeviceRequest. يربطsetCommissioningServiceالسمةAppCommissioningServiceبمثيلCommissioningService، ويتم عرضها في دالة رد اتصال. عند تمرير خدمة مخصّصة، ستكلّف حزمة تطوير البرامج (SDK) للأجهزة الجوّالة في المنزل الأجهزة أولاً بالانضمام إلى شبكة Android المحلية، ثم سترسل حمولة الإعداد إلىAppCommissioningService.val commissionDeviceRequest = CommissioningRequest.builder() .setCommissioningService(ComponentName( context, AppCommissioningService::class.java)) .build() - اتّصِل بالرقم
.getCommissioningClient()، ثم اتّصِل بالرقم.commissionDevice().
Matter.getCommissioningClient(context)
.commissionDevice(commissionDeviceRequest)
لإكمال الدالة commissionDevice، أضِف addOnSuccessListener وaddOnFailureListener:
.addOnSuccessListener { result ->
commissionDeviceLauncher.launch(IntentSenderRequest.Builder(result).build())
}
.addOnFailureListener { error ->
Timber.e(error)
}
5. إنشاء خدمة إعداد
في الدالة commissionDevice()، طلبنا الحصول على CommissioningService من CommissioningClient API. في هذا المسار، تعمل واجهة برمجة التطبيقات CommissioningClient على إعداد الأجهزة في Local Android fabric أولاً، ثم تعرض دالة رد اتصال تتضمّن الكائن 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 المخصّصة
لمساعدتك في البدء، حدّدنا مسبقًا بنية الفئة الأساسية لخدمة CommissioningService المخصّصة. في ما يلي نظرة عامة سريعة على وظائف الخدمة. للمتابعة، افتح AppCommissioningService في java/commissioning.
أضفنا عمليات الاستيراد التالية لواجهات برمجة التطبيقات الخاصة بحزمة Home Mobile SDK:
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: إلغاء onCommissioningRequested
لإضافة أجهزة إلى بيئة تطوير التطبيق، يُرجى إكمال الخطوات التالية:
- فتح
AppCommissioningServiceفيjava/commissioning. - ابحث عن الدالة
onCommissioningRequested(). لقد قدّمنا رسالة سجلّ تطبعCommissioningRequestMetadata. استبدِل التعليق// CODELAB: onCommissioningRequested()لبدء روتينserviceScopeالفرعي والحصول علىdeviceId.// Perform commissioning on custom fabric for the sample app. serviceScope.launch { val deviceId = devicesRepository.incrementAndReturnLastDeviceId() - إجراء عملية الإعداد بالنسبة إلى هذه الخطوة، يمكننا تمرير معلومات الجهاز التي تم عرضها في كائن 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 } - استخدِم
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 وشغِّل التطبيق. من الشاشة الرئيسية، انقر على إضافة جهاز وأكمِل الخطوات اللازمة لإعداد جهازك.
عند اكتمال عملية الإعداد، سيشارك جهازك الآن في شبكتَين: شبكة Android المحلية وشبكة التطوير المحلية. تحتوي كل شبكة على مجموعة بيانات اعتماد ومعرّف شبكة فريد يبلغ 64 بت.
6. التحكّم في الأجهزة
يتيح لك الإعداد في بيئة تطوير استخدام المكتبات من مستودع Matter (connectedhomeip) للتحكّم في الأجهزة من نموذج التطبيق.
لقد أنشأنا بعض الفئات المساعدة لتسهيل الوصول إلى مجموعات الأجهزة وإرسال الأوامر. لمزيد من المعلومات، افتح ClustersHelper في java/clusters. يستورد برنامج Singleton المساعد المكتبات التالية للوصول إلى معلومات الجهاز:
import chip.devicecontroller.ChipClusters import chip.devicecontroller.ChipStructs
يمكننا استخدام هذه الفئة للحصول على مجموعة On/Off لجهاز، ثم استدعاء .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 لتبديل حالة الجهاز.
- انتقِل إلى
DeviceViewModelفيjava/screens/device. - ابحث عن الدالة
updateDeviceStateOn. - استبدِل التعليق
// 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.
في الخطوات السابقة، تعرّفنا على أنّ حزمة تطوير البرامج (SDK) الخاصة بتطبيق Home Mobile تتيح إعداد الأجهزة في شبكة Local Android، وكذلك في شبكة تطوير لنموذج التطبيق. هذا مثال على عملية الإعداد المتعددة، حيث يمكن إعداد الأجهزة في أكثر من شبكة واحدة.
الآن، قد تحتاج إلى مشاركة الأجهزة مع المزيد من الأقمشة، خاصةً إذا كان هذا منزلًا يفضّل فيه كل فرد تطبيقات ومنصات مختلفة.
توفّر حزمة Home Mobile SDK هذه الوظيفة في ShareDeviceRequest API، ما يتيح لك إجراء ما يلي:
- افتح نافذة إعداد مؤقتة للأجهزة.
- غيِّر حالة أجهزتك لتتمكّن من إضافتها إلى شبكة أخرى.
- التحكّم في أجهزتك من تطبيقات وأنظمة بيئية أخرى
في الخطوات التالية، ستستخدم حزمة تطوير البرامج (SDK) للأجهزة الجوّالة في المنزل لمشاركة الأجهزة.
الخطوة 1: إنشاء مشغّل لنشاط نظام تحديد المواقع العالمي (GPS)
على غرار أداة تشغيل نشاط الإعداد التي أنشأناها عند الإعداد في بيئة تطوير، أنشأنا أداة تشغيل نشاط مشاركة الجهاز للتعامل مع IntentSender من CommissioningClient API.
- افتح
DeviceScreenفي المجلدjava/com/google/homesampleapp/screens/device/. - استبدِل التعليق
// 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 = remember {
{
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: استدعاء واجهة برمجة التطبيقات
حان الوقت الآن لبدء مهمة مشاركة الجهاز.
- افتح
DeviceScreen.ktفي مجلدjava/com/google/homesampleapp/screens/device/. - ابحث عن الدالة
shareDevice(). استبدِل التعليق// CODELAB: shareDeviceبالتعليقShareDeviceRequest. تقدّم السمةDeviceDescriptorمعلومات محدّدة عن الجهاز، مثل معرّف المورّد ومعرّف المنتج ونوع الجهاز. في هذا المثال، نُضمِّن القيم بشكل ثابت.val shareDeviceRequest = ShareDeviceRequest.builder() .setDeviceDescriptor(DeviceDescriptor.builder().build()) .setDeviceName("GHSAFM temp device name") - اضبط CommissioningWindow والمَعلمات.
.setCommissioningWindow( CommissioningWindow.builder() .setDiscriminator(Discriminator.forLongValue(DISCRIMINATOR)) .setPasscode(SETUP_PIN_CODE) .setWindowOpenMillis(SystemClock.elapsedRealtime()) .setDurationSeconds(OPEN_COMMISSIONING_WINDOW_DURATION_SECONDS.toLong()) .build()) .build() - استدعِ الدالة
.getCommissioningClient()، ولكن استخدِم واجهة برمجة التطبيقات.shareDevice()هذه المرة.Matter.getCommissioningClient(context) .shareDevice(shareDeviceRequest)
تقدّم دالة معاودة الاتصال الناجحة لواجهة برمجة التطبيقات commissioningClient.shareDevice() السمة IntentSender التي سيتم استخدامها لتشغيل ميزة "مشاركة نشاط الجهاز" في "خدمات Google Play".
- لإكمال الدالة
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.
يمكن لأجهزتك الآن المشاركة في ثلاث شبكات:
- The Local Android fabric.
- نسيج التطوير (هذا التطبيق)
- هذه هي الشبكة الثالثة التي شاركت الجهاز معها للتو.
8. الخطوات التالية
تهانينا
تهانينا، لقد أكملت هذا الدرس التطبيقي حول الترميز بنجاح وتعرّفت على كيفية إعداد الأجهزة ومشاركتها باستخدام حزمة تطوير البرامج (SDK) لتطبيق Home على الأجهزة الجوّالة.
إذا كنت تواجه مشاكل في نموذج التطبيق، جرِّب إكمال الخطوات التالية لإثبات ملكية بيئتك:
إذا كانت لديك أسئلة حول استخدام نموذج التطبيق أو اكتشفت خطأً في الرمز البرمجي، يمكنك إرسال المشاكل إلى Issue Tracker في مستودع GitHub:
للحصول على إرشادات رسمية من Google بشأن الأسئلة الفنية، يمكنك استخدام "منتدى المطوّرين في المنزل الذكي":
للحصول على الدعم الفني من المنتدى، استخدِم العلامة google-smart-home على Stack Overflow: