Permissions API ב-Android

לפני שמשתמשים באחד מממשקי ה-API של Home ל-Android, האפליקציה צריכה לקבל הרשאה לגשת למכשירים בבית של המשתמש, שנקראים ב-API המבנה. באמצעות Permissions API, המשתמש יכול להעניק לאפליקציות של Home APIs גישה למכשירים בבית שלו באמצעות חשבון Google שלו.

תהליך ההרשאה מאפשר למשתמש ליצור מבנה אם הוא עדיין לא הוגדר, בלי להשתמש ב-Google Home app (GHA).

שילוב Permissions API

לפני שממשיכים, חשוב לוודא שפעלתם לפי השלבים במאמר הגדרת הבית ב-Android. המופע homeManager מהשלב הזה משמש בכל הדוגמאות של Permissions כאן.

קודם כול צריך לרשום ActivityResultCaller ב-SDK. לדוגמה, כך אפליקציית הדוגמה מטפלת בזה:

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

בדיקת ההרשאות

לפני שאתם מבקשים הרשאות, מומלץ לבדוק אם המשתמש באפליקציה כבר נתן הסכמה לגישה למבנה. כדי לעשות את זה, קוראים ל-method hasPermissions() של מופע Home כדי לקבל Flow של ערכי PermissionsState:

val permissionsReadyState =
homeManager.hasPermissions().collect { state ->
    when (state) {
      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")

      PermissionsState.PERMISSIONS_STATE_UNINITIALIZED -> println(
          "Permissions state is not initialized yet. Clients should wait for another status update"
      )
      else ->
          throw IllegalStateException("""
            HomeClient.hasPermissions state should be PermissionsState.GRANTED,
            PermissionState.PERMISSIONS_STATE_UNINITIALIZED, or
            PermissionsState.PERMISSIONS_STATE_UNAVAILABLE. Actual state: $state
          """.trimIndent())
    }
}

אם הבדיקה מחזירה PermissionsState של NOT_GRANTED או PERMISSIONS_STATE_UNAVAILABLE, זה אומר שלמשתמש או לאפליקציה אין גישה למבנה. אם הבדיקה מחזירה PermissionsState of GRANTED אבל קריאה עוקבת אל structures() לא מחזירה מבנים, המשמעות היא שהמשתמש ביטל את הגישה לאפליקציה דרך דף ההגדרות GHA, או שאין לו את הגישה הנדרשת.

שליחת בקשה להרשאות

צריך להעניק הרשאה לאפליקציה כדי לגשת למבנים ולמכשירים בתוך מבנה נתון.

אם המשתמש עדיין לא העניק הרשאות, צריך להשתמש בשיטה requestPermissions() של מופע הבית כדי להפעיל את ממשק המשתמש של ההרשאות ולעבד את התוצאה:

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

כדי שממשק המשתמש של ההרשאות יופעל בצורה תקינה, צריך להגדיר OAuth לאפליקציה.

מתן הרשאות

עכשיו תוכלו להפעיל את האפליקציה ולבקש מהמשתמש להעניק הרשאות. סוגי המשתמשים שיכולים להעניק הרשאה וסוגי המכשירים שאפשר להעניק להם הרשאות משתנים בהתאם לשאלה אם רשמתם את האפליקציה ב-Google Home Developer Console.

נדרש רישום של Developer Console כדי לפרסם אפליקציה באמצעות ממשקי ה-API של Home. אין צורך לבדוק את ממשקי ה-API של Home כדי להשתמש בהם.

אם אפליקציה לא רשומה ב-Developer Console, היא תהיה במצב לא מאומת. מומלץ להשתמש בשיטה הזו כדי לבדוק את השימוש בממשקי ה-API של Home:

  • רק משתמשים שנרשמו כמשתמשי בדיקה במסוף OAuth יכולים להעניק הרשאות לאפליקציה. יש מגבלה של 100 משתמשי בדיקה לאפליקציה שלא אומתה.

  • לאפליקציה לא מאומתת תהיה גישה למכשירים מכל הסוגים שנתמכים על ידי OAuth עבור ממשקי ה-API של Home (רשימת סוגי המכשירים מופיעה בDeveloper Console). כל המכשירים במבנה יקבלו גישה.

אם אפליקציה רשומה ב-Developer Console ואושרה לה גישה לסוג מכשיר אחד או יותר, והושלם אימות המותג עבור OAuth, האפליקציה תהיה במצב מאומת. הסטטוס הזה נדרש כדי להשיק אפליקציה לייצור:

  • ההגבלות על חשבונות למטרות בדיקה כבר לא חלות. כל משתמש יכול להעניק הרשאה לאפליקציה.
  • המשתמש יכול להעניק הרשאה רק לסוגי המכשירים שאושרו בDeveloper Console.

עכשיו, אחרי שהגדרתם את OAuth, הקריאה של האפליקציה אל requestPermissions() מפעילה את תיבות הדו-שיח הבאות:

  1. המשתמש מתבקש לבחור את חשבון Google שבו הוא רוצה להשתמש.
  2. המשתמש מתבקש לבחור את המבנה שהוא רוצה להעניק לאפליקציה גישה אליו.
    1. באפליקציה לא מאומתת, כל סוגי המכשירים שנתמכים על ידי ממשקי ה-API של Home זמינים לאפליקציה.
    2. באפליקציה מאומתת, המשתמש יכול להעניק הרשאה רק לסוגי המכשירים שאושרו ב-Developer Console.
    3. בסוגי מכשירים רגישים שהאפליקציה יכולה לנהל, המשתמש יכול להגביל את הגישה לכל מכשיר בנפרד. לדוגמה, אם למשתמש יש שלוש נעילות, הוא יכול להעניק גישה רק לאחת מהן.
  • הסכמה ל-OAuth – בחירת חשבון
  • OAuth consent - link devices 01
  • הסכמה ל-OAuth – קישור מכשיר 02
איור 1: דוגמה לתהליך הסכמה ל-OAuth

אחרי שההרשאה ניתנת, האפליקציה יכולה להשתמש בממשקי ה-API של Home כדי לקרוא את המצב של המכשירים במבנה ולשלוט בהם. אם המשתמש לא מעניק לאפליקציה הרשאה לסוג מסוים של מכשיר או למכשיר רגיש, האפליקציה לא תוכל להשתמש בממשקי ה-API של Home כדי לגשת למכשיר, לשלוט בו או להגדיר אוטומציה שלו.

שינוי ההרשאות

כדי להעניק הרשאה לגישה למכשירים במבנה אחר, אפשר להפעיל את בורר החשבונות כדי לאפשר למשתמש לבחור את חשבון Google והמבנה שאליו הוא רוצה לעבור. במהלך התהליך הזה, מסך ההסכמה יוצג למשתמש שוב, גם אם הוא כבר הביע הסכמה בעבר.

אפשר לעשות זאת באמצעות קריאה חוזרת ל-requestPermissions() עם ההגדרה forceLaunch שמוגדרת ל-true:

homeManager.requestPermissions(forceLaunch=true)

שינוי הרשאות באמצעות רמזים לגבי המבנה

הצעות לגבי מבנה מאפשרות לאפליקציה לבחור מראש מבנה ספציפי, או להגביל את רשימת המבנים הזמינים, כשמבקשים שינוי מצטבר בהרשאות של ממשקי ה-API של Home של המשתמש. העברת פרמטרים של מבנה לבקשת ההרשאה תגרום לכך שתיבת הדו-שיח של ההרשאות תתמקד אוטומטית במבנה שנבחר, וכך תצמצם את החיכוך עם המשתמשים ותמנע שגיאות בהגדרות.

הניהול של רמזים למבנה מתבצע באמצעות מחלקת הנתונים ConsentScreenOptions. המחלקות ConsentScreenOptions מקבלות את פרמטרי ההגדרה הבאים:

  • structureId – מזהה הבית הספציפי שייבחר מראש בתיבת הדו-שיח של ההרשאה. כדי לקבל את הערך הזה, צריך לבדוק את מאפייני המבנה של המבנה שמעדכנים.
  • allowedStructureIds — רשימה של מזהי מבנה. אם מספקים את ההרשאות, בתיבת הדו-שיח של ההרשאות יוצגו רק המבנים שמופיעים ברשימה הזו. ברוב המקרים אפשר לא לציין את ההגדרה הזו, אלא אם רוצים לוודא שהמשתמש יישאר ברשימה של מבנים שכבר הוענקה להם גישה.
  • allowStructureChange — ההגדרה קובעת אם המשתמש מורשה לשנות את המבנה שנבחר מראש. ברוב המקרים, צריך להגדיר את הערך הזה ל-true אם צוין לפחות אחד מהערכים allowedStructureIds ו-structureId, כדי לתמוך בהתנהגות טבעית של המשתמש.

מעבירים את האובייקט הזה כפרמטר אופציונלי בקריאה requestPermissions(), עם הדגל forceLaunch שמוגדר ל-true:

import com.google.home.ConsentScreenOptions

// Create the ConsentScreenOptions class, allowing structure changes while
// ensuring the permissions dialog pre-selects the target structure on launch
val consentOptions = ConsentScreenOptions(
    structureId = target-structure-id,
    allowStructureChange = true
)

homeManager.requestPermissions(forceLaunch=true, consentOptions)

למשתמש יוצג מסך ההסכמה שכבר סונן לפי המבנה שצוין באובייקט ConsentScreenOptions.

המשתמשים יכולים להחליף מבנים באמצעות רמזים למבנה

אם למשתמש יש כמה מבנים באפליקציה ואתם רוצים לבחור מראש מבנה אחד, אבל עדיין לאפשר לו לעבור בין המבנים הזמינים, צריך להפעיל את השינויים במבנה באמצעות הדגל allowStructureChange ולספק רשימה של מבנים ב-allowedStructureIds:

val consentOptions = ConsentScreenOptions(
    structureId = target-structure-id,
    allowedStructureIds = listOf(target-structure-id, another-structure-id),
    allowStructureChange = true
)

ביטול הרשאות

המשתמשים יכולים לבטל גישה שהוענקה בעבר:

  1. דרך הדף 'החשבונות שלי' ב-Google > נתונים ופרטיות > אפליקציות ושירותים של צדדים שלישיים. הפעולה הזו תבטל את טוקן ה-OAuth שהונפק כשניתנה ההסכמה הראשונית, ותבטל את הגישה לכל מופע של האפליקציה שבה המשתמש השתמש בכל הפלטפורמות (טלפונים) והמבנים.

    יכול להיות שהמשתמש יופנה באמצעות קישור עומק לדף המשנה אפליקציות ושירותים של צד שלישי באמצעות סכימת כתובות ה-URL הבאה:

    https://myaccount.google.com/connections/link?project_number=Cloud project_number
    
  2. בדף GHA > הגדרות > אפליקציות מקושרות. כשלוחצים על בGHA, עוברים לדף הגדרות. משם, לוחצים על האריח אפליקציות מקושרות, שמוביל לדף שנראה דומה למסך הסכמה. בדף הזה המשתמש יכול להסיר את הגישה לאפליקציה. המשתמש יכול להשתמש באותו דף כדי לשנות את סוגי המכשירים או המכשירים הספציפיים הרגישים שאליהם יש לאפליקציה גישה.

במערכת האקולוגית של Google Home, ברוב סוגי המכשירים, המשתמשים יכולים להעניק הרשאות לכל המכשירים מאותו סוג בבת אחת. במכשירים רגישים או מוגבלים, כמו מנעולים, מצלמות או פעמונים, המשתמשים צריכים לתת הרשאה לכל אחד מהם בנפרד.

כדי לבדוק אם משתמש העניק הרשאה לגשת לסוג מכשיר רגיש או מוגבל, משתמשים בפונקציה consentedDeviceTypes() ברמת המבנה:

import com.google.home.Structure
import com.google.home.DeviceType
import com.google.home.DeviceTypeFactory
import com.google.home.consentedDeviceTypes // Extension function from the SDK
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
 * Example of how an app may monitor which device types have been granted access by a user.
 */
fun monitorDeviceConsent(structure: Structure, myScope: CoroutineScope) {
    // Obtain the flow of consented device type factories
    val consentedTypesFlow: Flow<Set<DeviceTypeFactory<out DeviceType>>> =
        structure.consentedDeviceTypes()

    myScope.launch {
        consentedTypesFlow.collect { consentedSet ->
            // Check if the user has consented to share a specific restricted
            // type, such as a Doorbell or Camera.
            val hasCameraAccess = consentedSet.any {
                it.toString() == "matter.google.type.GoogleDoorbellDevice"
            }

            if (hasCameraAccess) {
                // Enable features that require camera access
            } else {
                // Inform the user or disable camera-specific features
            }
        }
    }
}

הרשאות OkGoogle

הפקודה okGoogle היא פקודה ברמת המכשיר, ואפשר להשתמש בה כדי להפוך כל מכשיר במבנה לאוטומטי. עם זאת, יכול להיות שלאפליקציה עם ממשקי API של Home לא תהיה גישה לכל מכשיר. בטבלה הבאה מפורט איך ההרשאות נאכפות במקרים כאלה.

אוטומציה מאפיין אכיפת הרשאות
בשעה 22:00, אפשר להודיע ברמקול בחדר השינה שהגיע הזמן לישון. AssistantBroadcastTrait במכשיר. יצירת אוטומציה:
  • המכשיר שממנו משדרים צריך להיות מכשיר עם Assistant.
  • לאפליקציה ולמשתמש צריכה להיות גישה למכשיר שבו מתבצע השידור.
הפעלת אוטומציה:
  • לאפליקציה ולמשתמש צריכה להיות גישה למכשיר שבו מתבצע השידור.
בשעה 22:00, להודיע לכולם "שעת השינה" בכל המכשירים AssistantBroadcastTrait על מבנה. יצירת אוטומציה:
  • המבנה צריך לכלול לפחות מכשיר אחד עם Assistant שהאפליקציה והמשתמש יכולים לגשת אליו.
  • לאפליקציה ולמשתמש צריכה להיות גישה למבנה.
הפעלת אוטומציה:
  • לאפליקציה ולמשתמש צריכה להיות גישה למבנה.
בשעה 22:00, ‏"play some music" AssistantFulfillmentTrait.OkGoogleCommand יצירת אוטומציה:
  • לאפליקציה ולמשתמש צריכה להיות גישה למכשירים שהפעולות האוטומטיות שולחות להם פקודות.
הפעלת אוטומציה:
  • לאפליקציה ולמשתמש צריכה להיות גישה למכשירים שהפעולות האוטומטיות שולחות להם פקודות.
בכל פעם שמישהו אומר "הפעלת מוזיקה" VoiceStarterTrait.OkGoogleEvent יצירת אוטומציה:
  • לאפליקציה ולמשתמש צריכה להיות גישה למבנה. אוטומציה לא דורשת מכשיר עם Assistant כדי לעבור אימות או כדי לפעול, כי כל משתמש עם גישה למבנה יכול להשתמש בטלפון שלו (באמצעות אותו חשבון Google) כדי ליצור אינטראקציה עם Assistant ולהפעיל את VoiceStarter.
הפעלת אוטומציה:
  • האפליקציה לא דורשת הרשאה לגישה למכשיר שממנו מופעלת האוטומציה.
  • לאפליקציה ולמשתמש צריכה להיות הרשאה לגשת למכשיר שבו מתבצעת הפעולה.

הנחיות אם משתמש מבטל הרשאות מלאות

אם המשתמש מבטל את ההרשאות המלאות, כל האוטומציות הקיימות יפסיקו לפעול. בנוסף, אם המשתמש מבטל את הגישה למכשירים ספציפיים, הפעולות, התנאים והטריגרים שמשויכים למכשירים האלה יפסיקו לפעול.

בכל פעם שהאפליקציה מופעלת, חשוב לוודא שההרשאות עדיין בתוקף. אם הן בוטלו, צריך לוודא שכל הנתונים הקודמים הוסרו, כולל נתונים ששמורים במטמון באפליקציה.