Permissions API trên Android

Trước khi sử dụng bất kỳ API Home nào cho Android, ứng dụng phải có quyền truy cập vào các thiết bị trong nhà của người dùng (trong API được gọi là cấu trúc). Với Permissions API, người dùng có thể cấp cho các ứng dụng Home APIs quyền truy cập vào các thiết bị trong nhà của họ bằng Tài khoản Google.

Tích hợp Permissions API

Trước khi tiếp tục, hãy đảm bảo bạn đã làm theo hướng dẫn Khởi động nhà trên Android. Phiên bản homeManager từ bước đó được dùng trong tất cả các ví dụ về Quyền ở đây.

Trước tiên, hãy đăng ký một ActivityResultCaller bằng SDK. Ví dụ: đây là cách ứng dụng mẫu xử lý vấn đề này:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    homeManager.registerActivityResultCallerForPermissions(this)
  }

Kiểm tra quyền

Trước khi yêu cầu cấp quyền, bạn nên kiểm tra xem người dùng ứng dụng đã đồng ý hay chưa. Để làm việc này, hãy gọi phương thức hasPermissions() của thực thể Home để lấy Flow gồm các giá trị PermissionsState:

val permissionsReadyState =
  homeManager.hasPermissions().collect { state ->
    state == PermissionsState.GRANTED ||
      state == PermissionsState.PERMISSIONS_STATE_UNAVAILABLE ||
      state == PermissionsState.NOT_GRANTED
    when (permissionsReadyState) {
      PermissionsState.GRANTED -> println("Permissions granted, no need to request permissions")
      PermissionsState.PERMISSIONS_STATE_UNAVAILABLE ->
        println("Permissions state unavailable, request permissions")
      PermissionsState.NOT_GRANTED ->
        println("OAuth permission is enabled but not granted yet, request permissions")
      else ->
        throw IllegalStateException(
          "HomeClient.hasPermissions state should be PermissionsState.GRANTED or " +
            "PermissionsState.PERMISSIONS_STATE_UNAVAILABLE")
  }
}

Nếu quá trình kiểm tra trả về PermissionsStateNOT_GRANTED hoặc PERMISSIONS_STATE_UNAVAILABLE, bạn nên yêu cầu cấp quyền. Nếu quá trình kiểm tra trả về PermissionsStateGRANTED nhưng một lệnh gọi tiếp theo đến structures() không trả về cấu trúc nào, thì người dùng đã thu hồi quyền truy cập vào ứng dụng thông qua trang cài đặt Google Home app (GHA) và bạn nên yêu cầu cấp quyền. Nếu không, người dùng sẽ có quyền truy cập.

Yêu cầu cấp quyền

Bạn phải cấp quyền cho ứng dụng để truy cập vào các cấu trúc và thiết bị trong một cấu trúc nhất định.

Nếu người dùng chưa cấp quyền, hãy sử dụng phương thức requestPermissions() của thực thể Home để chạy Giao diện người dùng Quyền và xử lý kết quả:

fun requestPermissions(scope: CoroutineScope, onShowSnackbar: (String) -> Unit) {
  scope.launch {
    val result =
      try {
        homeManager.requestPermissions()
      } catch (e: HomeException) {
        PermissionsResult(
          PermissionsResultStatus.ERROR,
          "Got HomeException with error: ${e.message}",
        )
      }
    when (result.status) {
      PermissionsResultStatus.SUCCESS -> {
        Log.i(TAG, "Permissions successfully granted.")
      }
      PermissionsResultStatus.CANCELLED -> {
        Log.i(TAG, "User cancelled Permissions flow.")
        onShowSnackbar("User cancelled Permissions flow")
      }
      else -> {
        Log.e(
          TAG,
          "Failed to grant permissions with error: ${result.status}, ${result.errorMessage}",
        )
        onShowSnackbar("Failed to grant permissions with error: ${result.errorMessage}")
      }
    }
  }
}

Để giao diện người dùng Quyền khởi chạy đúng cách, bạn phải thiết lập OAuth cho ứng dụng của mình.

Cấp quyền

Giờ đây, bạn có thể chạy ứng dụng và yêu cầu người dùng cấp quyền. Loại người dùng có thể cấp quyền và loại thiết bị có thể cấp quyền sẽ khác nhau tuỳ thuộc vào việc bạn đã đăng ký ứng dụng của mình trong Google Home Developer Console hay chưa.

Bạn phải đăng ký Developer Console để xuất bản ứng dụng bằng Home API. Bạn không bắt buộc phải kiểm thử và sử dụng Home API.

Nếu một ứng dụng không được đăng ký trong Developer Console, thì ứng dụng đó sẽ ở trạng thái chưa được xác minh. Bạn nên dùng cách này để kiểm thử việc sử dụng Home API:

  • Chỉ những người dùng đã đăng ký làm người dùng thử nghiệm trong bảng điều khiển OAuth mới có thể cấp quyền cho ứng dụng. Ứng dụng chưa được xác minh chỉ có thể có tối đa 100 người dùng thử nghiệm.

  • Ứng dụng chưa được xác minh sẽ có quyền truy cập vào các thiết bị thuộc mọi loại thiết bị mà OAuth hỗ trợ cho Home API (danh sách các loại thiết bị trong Developer Console). Tất cả thiết bị trong một cấu trúc sẽ được cấp quyền.

Nếu một ứng dụng được đăng ký trong Developer Console và đã được phê duyệt quyền truy cập vào một hoặc nhiều loại thiết bị, đồng thời quy trình xác minh thương hiệu đã hoàn tất cho OAuth, thì ứng dụng đó sẽ ở trạng thái đã xác minh. Bạn phải ở trạng thái này để ra mắt ứng dụng cho người dùng thực tế:

  • Giới hạn về số lượng người dùng thử nghiệm sẽ không còn áp dụng nữa. Mọi người dùng đều có thể cấp quyền cho ứng dụng.
  • Người dùng chỉ có thể cấp quyền cho các loại thiết bị đã được phê duyệt trong Developer Console.

Sau khi bạn thiết lập OAuth, lệnh gọi của ứng dụng đến requestPermissions() sẽ kích hoạt các hộp thoại sau:

  1. Người dùng sẽ được nhắc chọn Tài khoản Google mà họ muốn sử dụng.
  2. Người dùng sẽ được nhắc chọn cấu trúc mà họ muốn cấp quyền truy cập cho ứng dụng.
    1. Đối với một ứng dụng chưa được xác minh, ứng dụng có thể sử dụng tất cả các loại thiết bị mà Home API hỗ trợ.
    2. Đối với một ứng dụng đã xác minh, người dùng chỉ có thể cấp quyền cho các loại thiết bị đã được phê duyệt trong Developer Console.
    3. Đối với các loại thiết bị nhạy cảm mà ứng dụng có quyền quản lý, người dùng có thể hạn chế quyền truy cập theo từng thiết bị. Ví dụ: nếu có 3 khoá, người dùng chỉ có thể cấp quyền truy cập cho một trong số các khoá đó.
  • Sự đồng ý qua OAuth – chọn tài khoản
  • Sự đồng ý qua OAuth – liên kết thiết bị 01
  • Sự đồng ý qua OAuth – liên kết thiết bị 02
Hình 1: Ví dụ về quy trình đồng ý OAuth

Sau khi được cấp quyền, ứng dụng có thể sử dụng Home API để đọc trạng thái và điều khiển các thiết bị trong cấu trúc. Nếu người dùng không cấp quyền cho ứng dụng đối với một loại thiết bị cụ thể hoặc thiết bị nhạy cảm, thì ứng dụng sẽ không thể dùng Home API để truy cập, điều khiển hoặc tự động hoá thiết bị đó.

Thay đổi quyền

Để cấp quyền truy cập vào các thiết bị trong một cấu trúc khác, bạn có thể khởi chạy trình chọn tài khoản để cho phép người dùng chọn Tài khoản Google và cấu trúc cần chuyển sang. Trong quá trình này, người dùng sẽ thấy lại màn hình đồng ý, ngay cả khi trước đó họ đã đồng ý.

Bạn có thể thực hiện việc này bằng cách gọi lại requestPermissions() với cờ forceLaunch được đặt thành true:

homeManager.requestPermissions(forceLaunch=true)

Thu hồi quyền

Người dùng có thể thu hồi quyền truy cập đã cấp trước đó:

  1. Thông qua trang Tài khoản của tôi trên Google > Dữ liệu và quyền riêng tư > Ứng dụng và dịch vụ của bên thứ ba. Thao tác này sẽ thu hồi mã thông báo OAuth được cấp khi người dùng đồng ý lần đầu và thu hồi quyền truy cập vào mọi phiên bản của ứng dụng mà người dùng đang sử dụng trên tất cả các nền tảng (điện thoại) và cấu trúc.

    Người dùng có thể được chuyển hướng bằng một đường liên kết sâu đến trang phụ Ứng dụng và dịch vụ của bên thứ ba bằng cách sử dụng lược đồ URL sau:

    https://myaccount.google.com/connections/link?project_number=Cloud project_number
    
  2. Thông qua trang GHA > Cài đặt > Ứng dụng được liên kết. Khi nhấp vào biểu tượng trong GHA, bạn sẽ được chuyển đến trang Cài đặt. Từ đó, hãy nhấp vào ô Ứng dụng được liên kết. Thao tác này sẽ đưa bạn đến một trang có giao diện tương tự như màn hình đồng ý. Từ trang này, người dùng có thể xoá quyền truy cập vào ứng dụng. Người dùng có thể sử dụng chính trang này để thay đổi loại thiết bị hoặc thiết bị nhạy cảm cụ thể mà ứng dụng có thể truy cập.

Quyền truy cập OkGoogle

Lệnh okGoogle là một lệnh ở cấp thiết bị và có thể dùng để tự động hoá mọi thiết bị trong cấu trúc. Tuy nhiên, một ứng dụng Home APIs có thể không có quyền truy cập vào mọi thiết bị. Bảng sau đây mô tả cách các quyền được thực thi trong những trường hợp như vậy.

Tự động hóa Đặc điểm Thực thi quyền
Lúc 10:00 tối, phát thông báo "Giờ đi ngủ" trên loa phòng ngủ. AssistantBroadcastTrait trên thiết bị. Tạo quy trình tự động hoá:
  • Thiết bị phát phải là thiết bị có Trợ lý.
  • Ứng dụng và người dùng phải có quyền truy cập vào thiết bị phát sóng.
Thực thi tự động hoá:
  • Ứng dụng và người dùng phải có quyền truy cập vào thiết bị phát sóng.
Lúc 10 giờ tối, phát thông báo "Đã đến giờ đi ngủ" trên tất cả các thiết bị AssistantBroadcastTrait về cấu trúc. Tạo quy trình tự động hoá:
  • Phải có ít nhất một thiết bị có Trợ lý trong cấu trúc mà ứng dụng và người dùng có quyền truy cập.
  • Ứng dụng và người dùng phải có quyền truy cập vào cấu trúc.
Thực thi tự động hoá:
  • Ứng dụng và người dùng phải có quyền truy cập vào cấu trúc.
Vào lúc 10:00 tối, "phát nhạc" AssistantFulfillmentTrait.OkGoogleCommand Tạo quy trình tự động hoá:
  • Ứng dụng và người dùng phải có quyền truy cập vào các thiết bị mà quy trình tự động hoá đưa ra lệnh.
Thực thi tự động hoá:
  • Ứng dụng và người dùng phải có quyền truy cập vào các thiết bị mà quy trình tự động hoá đưa ra lệnh.
Bất cứ khi nào có người nói "phát nhạc" VoiceStarterTrait.OkGoogleEvent Tạo quy trình tự động hoá:
  • Ứng dụng và người dùng phải có quyền truy cập vào cấu trúc. Chế độ Tự động hoá không yêu cầu thiết bị Trợ lý vượt qua quy trình xác thực hoặc chạy, vì bất kỳ người dùng nào có quyền truy cập vào cấu trúc đều có thể sử dụng điện thoại (bằng cùng một Tài khoản Google) để tương tác với Trợ lý và kích hoạt VoiceStarter.
Thực thi tự động hoá:
  • Ứng dụng không yêu cầu quyền truy cập vào thiết bị bắt đầu quy trình tự động hoá.
  • Ứng dụng và người dùng phải có quyền truy cập vào thiết bị mà hành động diễn ra.