Khởi chạy trang chủ trên Android

Trước khi sử dụng bất kỳ API Home nào cho Android, bạn phải khởi chạy Home trong ứng dụng. Trong bước này, bạn sẽ tạo một thực thể singleton của Home cho bối cảnh cục bộ.

Chỉ một thực thể của Home được hoạt động tại một thời điểm.

Đây là điểm truy cập vào API Home và cũng liên quan đến việc khai báo những đặc điểm và loại thiết bị mà bạn dự định sử dụng với API Thiết bị và cấu trúc cũng như API Tự động hoá. Nếu bạn mới bắt đầu sử dụng hệ sinh thái Google Home và không chắc chắn nên đăng ký những đặc điểm hoặc loại thiết bị nào, thì chúng tôi đã đề xuất một số đặc điểm và loại thiết bị phổ biến nhất trong hướng dẫn này.

Tạo thực thể Home

Để bắt đầu, hãy nhập các gói này vào ứng dụng:

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

Cách khởi chạy API Home:

  1. Lấy tham chiếu đến bối cảnh Application. Bối cảnh này không phụ thuộc vào bất kỳ vòng đời của activity nào và sẽ tồn tại miễn là ứng dụng của bạn còn hoạt động. Bạn có thể lấy bối cảnh này bằng cách gọi getApplicationContext() trong một Activity hoặc Service:

    val context = getApplicationContext()
    
  2. Tạo một FactoryRegistry thực thể với tất cả các đặc điểm và loại thiết bị mà bạn dự định sử dụng trong ứng dụng.

    Trong hướng dẫn này, chúng tôi đã đề xuất một số đặc điểm và loại thiết bị phổ biến (các loại thiết bị Đèn, Phích cắm, Cảm biến, Công tắc và Bộ điều nhiệt, các đặc điểm về sự hiện diện và Trợ lý cho tính năng tự động hoá), trong trường hợp bạn không chắc chắn về những gì mình cần. Để tìm hiểu thêm, hãy xem phần Đăng ký đặc điểm và loại thiết bị.

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

    Bạn phải nhập các câu lệnh cho từng đặc điểm và loại thiết bị đã đăng ký tại đây (Android Studio sẽ nhắc bạn thêm các câu lệnh này).

  3. Tạo thực thể HomeConfig bằng Dispatchers.IO bối cảnh coroutine và thực thể đăng ký.

    val homeConfig = HomeConfig(
            coroutineContext = Dispatchers.IO,
            factoryRegistry = registry)
    
  4. Cuối cùng, hãy tạo thực thể singleton của Home. Đây là điểm truy cập vào các API, sử dụng bối cảnh và HomeConfig.

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

Để tránh lỗi với các phiên không hợp lệ, bạn chỉ nên tạo một thực thể singleton của Home bằng cách gói thực thể đó trong một câu lệnh đối tượng.

Ví dụ: Ứng dụng mẫu thực hiện theo cách này:

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

Đăng nhập bằng Google do ứng dụng khởi chạy

Bạn có thể muốn quản lý thông tin xác thực Google của người dùng trong ứng dụng. Khi làm như vậy, bạn có thể sử dụng cùng một tài khoản người dùng trên nhiều dịch vụ của Google, chẳng hạn như Google Home, Drive, Maps, v.v.

Với tính năng đăng nhập bằng Google do ứng dụng khởi chạy, bạn có thể lấy một thực thể HomeClient được liên kết rõ ràng với một người dùng cụ thể, nhờ đó bỏ qua trình chọn Tài khoản Google và màn hình xin phép khi tài khoản đã được uỷ quyền.

Ngoài ra, phương pháp này giúp người dùng không nhìn thấy hai màn hình chọn tài khoản khác nhau – một màn hình từ tính năng đăng nhập của ứng dụng và một màn hình từ Google Home.

Để thực hiện việc này, bạn phải tham khảo bài viết Xác thực người dùng bằng tính năng Đăng nhập bằng Google và hoàn tất các bước sau:

Tạo mã ứng dụng web OAuth

  1. Mở Google Cloud Console
    • Chuyển đến trang Thông tin đăng nhập của Google Cloud Console.
    • Chọn một dự án hiện có hoặc tạo một dự án mới.
  2. Định cấu hình màn hình xin phép bằng OAuth (nếu bạn chưa làm)
    • Trước khi tạo thông tin đăng nhập, hãy đảm bảo rằng màn hình xin phép bằng OAuth được định cấu hình với thông tin chi tiết về ứng dụng của bạn, bao gồm cả chính sách quyền riêng tư và URL điều khoản dịch vụ.
  3. Tạo mã ứng dụng OAuth (loại Ứng dụng web)
    • Trên trang Thông tin đăng nhập, hãy nhấp vào + CREATE CREDENTIALS rồi chọn Mã ứng dụng OAuth trong trình đơn thả xuống.
    • Đối với Loại ứng dụng, hãy chọn Ứng dụng web.
    • Nhập tên cho ứng dụng web (ví dụ: "Phần phụ trợ web của ứng dụng").
    • Nhấp vào Tạo.
  4. Truy xuất mã ứng dụng
    • Sau khi tạo, bảng điều khiển sẽ hiển thị mã ứng dụng mới. Đây là giá trị mà bạn sẽ sử dụng trong ứng dụng Android (ví dụ: "{project number}-.....apps.googleusercontent.com")
    • Bạn nên lưu trữ mã ứng dụng bên ngoài (ví dụ: trong build.gradle) thay vì mã hoá cứng trực tiếp

Tạo thực thể cho yêu cầu Đăng nhập bằng Google

Sử dụng mã ứng dụng web để tạo yêu cầu đăng nhập bằng Google:

// 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()

Tạo quy trình Đăng nhập bằng Google

Để triển khai quy trình đăng nhập, hãy sử dụng CredentialManager để thực thi yêu cầu Sign in with Google. Sau khi người dùng chọn một tài khoản, hãy trích xuất email của họ từ Mã thông báo Google ID kết quả để tạo android.accounts.Account. Sau đó, tài khoản này được dùng để khởi chạy một thực thể HomeClient được liên kết cụ thể với người dùng đã đăng nhập đó.

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

Lấy thực thể HomeClient mới

Hãy làm theo các bước tương tự được nêu trong Tạo thực thể Home, nhưng thay vì gọi Home.getClient(context, homeConfig) ở Bước 4, hãy gọi Home.getClient(context, userAccount, homeConfig), trong đó tham số thứ hai là Lazy<UserAccount>. Thao tác này sẽ trả về một thực thể của HomeClientWithProvidedAccount, một lớp con của HomeClient, được liên kết rõ ràng với Tài khoản Google đã chỉ định:

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

Nếu người dùng được chỉ định không được uỷ quyền, hãy nhắc người dùng cấp quyền bằng cách gọi các phương thức sau trên HomeClientWithProvidedAccount thực thể:

  1. registerActivityResultCallerForPermissions() có tham chiếu đến ActivityResultCaller mà bạn muốn sử dụng.
  2. requestPermissions(). Thao tác này sẽ hiển thị màn hình xin phép của GHP, nơi người dùng có thể cấp quyền.

Bạn có thể tạo HomeClient bằng UserAccount, sau đó gọi requestPermissions() bằng forceLaunch==true để khởi chạy lại màn hình xin phép, cho phép người dùng cập nhật quyền được cấp:

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

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

Hãy xem API Quyền để biết thêm thông tin về cách quản lý quyền đối với API Home.

Làm mới toàn bộ hoạt động bằng HomeClient mới

Sau khi có thực thể HomeClient mới, bạn phải làm mới toàn bộ hoạt động để đăng ký lại và tìm nạp cấu trúc, thiết bị hoàn chỉnh cũng như các dữ liệu liên quan khác được liên kết với tài khoản người dùng này.

Đăng ký đặc điểm và loại thiết bị

Lớp FactoryRegistry giúp nhà phát triển tối ưu hoá kích thước tệp nhị phân của ứng dụng bằng cách cho phép họ chỉ định rõ ràng những đặc điểm và loại thiết bị mà ứng dụng của họ sử dụng.

Xin lưu ý rằng quyền và sổ đăng ký nhà máy được tách rời. Do đó, bạn không thể truy cập vào các đặc điểm và loại chưa đăng ký mà ứng dụng của bạn có thể sử dụng bằng quyền nhưng không có trong sổ đăng ký nhà máy bằng API Tự động hoá, cũng như không được trả về trong các lệnh gọi phương thức hàng loạt traits() hoặc types().