خانه را در اندروید راه اندازی کنید

قبل از استفاده از هر یک از APIهای Home برای اندروید، باید home را در برنامه خود مقداردهی اولیه کنید. در این مرحله، یک نمونه تک‌لایه از Home را برای زمینه محلی ایجاد خواهید کرد.

فقط یک نمونه از Home باید در یک زمان فعال باشد.

این نقطه ورود به APIهای Home است و همچنین شامل اعلام ویژگی‌ها و انواع دستگاه‌هایی است که قصد دارید با APIهای Device & Structure و Automation استفاده کنید. اگر تازه کار با اکوسیستم Google Home را شروع کرده‌اید و مطمئن نیستید که چه ویژگی‌ها یا انواع دستگاه‌هایی را ثبت کنید، ما در این راهنما برخی از رایج‌ترین‌ها را پیشنهاد کرده‌ایم.

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

برای شروع، این بسته‌ها را به برنامه خود وارد کنید:

import android.content.Context
import com.google.home.FactoryRegistry
import com.google.home.HomeConfig
import com.google.home.Home

برای مقداردهی اولیه API های Home:

  1. یک ارجاع به زمینه Application context) دریافت کنید. این زمینه به هیچ چرخه حیات فعالیتی وابسته نیست و تا زمانی که برنامه شما زنده است، وجود خواهد داشت. می‌توانید آن را با فراخوانی getApplicationContext() در یک Activity یا Service دریافت کنید:

    val context = getApplicationContext()
    
  2. یک نمونه FactoryRegistry با تمام ویژگی‌ها و انواع دستگاه‌هایی که قصد دارید در برنامه خود استفاده کنید، ایجاد کنید.

    در این راهنما، برخی از موارد رایج (انواع دستگاه‌های روشنایی، پریز، حسگر، کلید و ترموستات، ویژگی‌های حضور و دستیار برای اتوماسیون‌ها) را پیشنهاد کرده‌ایم، در صورتی که مطمئن نیستید به چه چیزی نیاز دارید. برای کسب اطلاعات بیشتر، به ثبت ویژگی‌ها و انواع دستگاه مراجعه کنید.

    val registry = FactoryRegistry(
      traits = listOf(
                AirQuality,
                AreaAttendanceState,
                AreaPresenceState,
                AssistantBroadcast,
                AssistantFulfillment,
                BooleanState,
                ColorControl,
                ExtendedColorControl,
                FlowMeasurement,
                IlluminanceMeasurement,
                LevelControl,
                Notification,
                OccupancySensing,
                OnOff,
                RelativeHumidityMeasurement,
                Switch,
                TemperatureMeasurement,
                Thermostat),
      types = listOf(
                AirQualitySensorDevice,
                ColorDimmerSwitchDevice,
                ColorTemperatureLightDevice,
                ContactSensorDevice,
                DimmableLightDevice,
                DimmablePlugInUnitDevice,
                DimmerSwitchDevice,
                ExtendedColorLightDevice,
                FlowSensorDevice,
                GenericSwitchDevice,
                HumiditySensorDevice,
                LightSensorDevice,
                OccupancySensorDevice,
                OnOffLightDevice,
                OnOffLightSwitchDevice,
                OnOffPluginUnitDevice,
                OnOffSensorDevice,
                SpeakerDevice,
                TemperatureSensorDevice,
                ThermostatDevice))
    

    دستورات ایمپورت برای هر ویژگی و نوع دستگاه ثبت شده در اینجا الزامی است ( Android Studio باید از شما بخواهد که این موارد را اضافه کنید).

  3. با استفاده از زمینه کوروتین Dispatchers.IO و نمونه رجیستری خود، یک HomeConfig نمونه‌سازی کنید.

    val homeConfig = HomeConfig(
            coroutineContext = Dispatchers.IO,
            factoryRegistry = registry)
    
  4. در نهایت، با استفاده از context و HomeConfig ، یک نمونه تک‌لایه از Home ایجاد کنید که نقطه ورود به APIها است.

    val homeManager: HomeClient = Home.getClient(context, homeConfig)
    

برای جلوگیری از خطاهای مربوط به session های نامعتبر، مهم است که فقط یک نمونه singleton از Home ایجاد شود ، که این کار با قرار دادن آن در یک اعلان شیء انجام می‌شود.

برای مثال، برنامه Sample این کار را به این صورت انجام می‌دهد:

internal object HomeClientModule {
  @Provides
  @Singleton
  fun provideHomeClient(@ApplicationContext context: Context): HomeClient {
    return Home.getClient(
      context,
      HomeConfig(
        coroutineContext = IODispatcherModule.provideIoDispatcher(),
        factoryRegistry = registry,
      ),
    )
  }
}

ورود به سیستم گوگل از طریق برنامه

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

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

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

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

یک شناسه کلاینت برنامه وب OAuth ایجاد کنید

  1. کنسول ابری گوگل را باز کنید
    • به صفحه اعتبارنامه‌های کنسول گوگل کلود بروید.
    • یک پروژه موجود را انتخاب کنید یا یک پروژه جدید ایجاد کنید.
  2. صفحه موافقت OAuth را پیکربندی کنید (اگر این کار را نکرده‌اید)
    • قبل از ایجاد اعتبارنامه، مطمئن شوید که صفحه رضایت OAuth با جزئیات برنامه شما، از جمله سیاست حفظ حریم خصوصی و URL های شرایط خدمات، پیکربندی شده است.
  3. ایجاد شناسه کلاینت OAuth (نوع برنامه وب)
    • در صفحه اعتبارنامه‌ها، روی + CREATE CREDENTIALS کلیک کنید و از منوی کشویی، OAuth client ID را انتخاب کنید.
    • برای نوع برنامه ، برنامه وب را انتخاب کنید.
    • یک نام برای کلاینت وب خود وارد کنید (مثلاً "My App Web Backend").
    • روی ایجاد کلیک کنید.
  4. بازیابی شناسه مشتری
    • پس از ایجاد، کنسول، شناسه کلاینت جدید شما را نمایش می‌دهد. این مقداری است که در برنامه اندروید خود استفاده خواهید کرد (مثلاً " {project number}-.....apps.googleusercontent.com ")
    • توصیه می‌شود که شناسه کلاینت را به صورت خارجی (مثلاً در build.gradle ) ذخیره کنید، نه اینکه مستقیماً آن را در کدنویسی سخت قرار دهید.

یک درخواست ورود به سیستم گوگل را نمونه‌سازی کنید

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

// Your Google Cloud console Web Client ID for Google Sign-In
val serverClientId = BuildConfig.DEFAULT_WEB_CLIENT_ID

// Build the request for Google ID token
val googleIdOption = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(false) // Show all Google Accounts on the device
    .setServerClientId(serverClientId) // embed WebClientID in token
    .build()

// Build the GetCredentialRequest
val request = GetCredentialRequest.Builder().addCredentialOption(googleIdOption).build()

ایجاد جریان ورود با گوگل

برای پیاده‌سازی جریان ورود به سیستم، از CredentialManager برای اجرای درخواست Sign in with Google استفاده کنید. پس از انتخاب حساب کاربری توسط کاربر، ایمیل او را از توکن شناسه گوگل حاصل استخراج کنید تا یک android.accounts.Account ایجاد شود. سپس از این حساب برای مقداردهی اولیه یک نمونه HomeClient که به‌طور خاص به آن کاربر وارد شده مرتبط است، استفاده می‌شود.

  try {
    // CredentialManager is responsible for interacting with various credential providers on the device
    val credentialManager = CredentialManager.create(context)
    // Credential returns when user has selected an account and the getCredential call completes
    val result = credentialManager.getCredential(context = context, request = request)
    val credential = result.credential

    if (
      credential is CustomCredential &&
      credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
    ) {
      try {
        val googleCredential = GoogleIdTokenCredential.createFrom(credential.data)
        googleCredential.id.let { userEmail ->
          Log.i(TAG, "Email found in Google ID Token: $email")
          /*
           Why "com.google"?
           The string "com.google" is a standard identifier used in Android's android.accounts.
           Account system to represent accounts managed by Google. This is often used when
           interacting with Android's Account Manager or when using Google-specific APIs. So,
           even if the email ends in "@gmail.com", the underlying account type or provider is
           still considered "com.google" within the Android system.
          */
          val account = Account(userEmail, "com.google")
          Log.d(TAG,"Switched account to : $userEmail")
          // Get the new Home Client Instance with the userEmail
        }
        Log.i(TAG, "Account switch complete. Emitting navigation event.")
      } catch (e: Exception) {
        Log.e(TAG,"Could not convert CustomCredential to Google ID Token", e)
      }
    }
  } catch (e: Exception) {
    Log.e(TAG, "Google Sign-In failed with unexpected error", e)
  }

یک نمونه جدید HomeClient دریافت کنید

همان مراحل ذکر شده در بخش «ایجاد یک نمونه Home» را دنبال کنید، اما به جای فراخوانی Home.getClient(context, homeConfig) در مرحله ۴، Home.getClient(context, userAccount, homeConfig) را فراخوانی کنید، که پارامتر دوم آن Lazy<UserAccount> است. این کار نمونه‌ای از HomeClientWithProvidedAccount را برمی‌گرداند، که یک زیرکلاس از HomeClient است و به صراحت به حساب گوگل مشخص شده گره خورده است:

val client =
     Home.getClient(
       context = context.applicationContext,
       account =
         lazy {
         // 1. Create the Account object.
           val androidAccount = Account(userEmail,
                                        GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE)
         // 2. Wrap it in UserAccount.GoogleAccount.
           UserAccount.GoogleAccount(androidAccount)
         },
       homeConfig = HomeConfig()
     )

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

  1. registerActivityResultCallerForPermissions() ‎ به همراه ارجاعی به ActivityResultCaller که می‌خواهید استفاده کنید.
  2. requestPermissions() . این کار صفحه موافقت GHP را نمایش می‌دهد، جایی که کاربر می‌تواند مجوز خود را اعطا کند.

شما می‌توانید یک HomeClient با یک UserAccount ایجاد کنید و سپس requestPermissions() را با forceLaunch==true فراخوانی کنید تا دوباره صفحه رضایت‌نامه نمایش داده شود و به کاربر اجازه دهید مجوزهای اعطایی خود را به‌روزرسانی کند:

val client =
     Home.getClient(
       context = context.applicationContext,
       account =
         lazy {
              UserAccount.GoogleAccount(androidAccount)
         },
       homeConfig = HomeConfig()
     )

client.registerActivityResultCallerForPermissions(this)
client.requestPermissions(forceLaunch= true)

برای اطلاعات بیشتر در مورد مدیریت مجوزهای APIهای خانگی، به API مجوزها مراجعه کنید.

کل فعالیت را با HomeClient جدید رفرش کنید

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

ثبت ویژگی‌ها و انواع دستگاه‌ها

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

توجه داشته باشید که مجوزها و رجیستری کارخانه از هم جدا هستند. بنابراین، ویژگی‌ها و انواع ثبت نشده‌ای که با استفاده از مجوزها در برنامه شما در دسترس هستند اما در رجیستری کارخانه گنجانده نشده‌اند، با استفاده از API اتوماسیون غیرقابل دسترسی هستند و همچنین در فراخوانی‌های متدهای traits() یا types() بازگشت داده نمی‌شوند.