قبل استخدام أي من واجهات برمجة التطبيقات Home APIs لنظام التشغيل Android، يجب أن يحصل التطبيق على إذن بالوصول إلى الأجهزة في منزل المستخدم، ويُشار إليها في واجهة برمجة التطبيقات باسم البنية. باستخدام Permissions API، يمكن للمستخدم منح تطبيقات Home APIs إذن الوصول إلى الأجهزة في منزله باستخدام حسابه على Google.
يتيح مسار الأذونات للمستخدم إنشاء بنية إذا لم يتم إعدادها من قبل، بدون الحاجة إلى استخدام Google Home app (GHA).
دمج واجهة Permissions API
قبل المتابعة، تأكَّد من اتّباع الخطوات الواردة في مقالة
إعداد المنزل على Android.
يتم استخدام مثيل homeManager من تلك الخطوة في جميع أمثلة الأذونات الواردة هنا.
عليك أولاً تسجيل
ActivityResultCaller
باستخدام حزمة تطوير البرامج (SDK). إليك مثلاً طريقة تعامل التطبيق النموذجي مع ذلك:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
homeManager.registerActivityResultCallerForPermissions(this)
}
التحقّق من الأذونات
قبل طلب الأذونات، ننصحك بالتحقّق مما إذا كان مستخدم التطبيق قد منح موافقته على الوصول إلى البنية. لإجراء ذلك، استدعِ طريقة
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
من GRANTED ولكن لم تعرض مكالمة لاحقة إلى structures() أي بنى،
يعني ذلك أنّ المستخدم إما ألغى إذن الوصول
إلى التطبيق من خلال صفحة إعدادات GHA، أو أنّ المستخدم
لا يملك إذن الوصول المطلوب.
طلب الحصول على الأذونات
يجب منح تطبيقك الإذن بالوصول إلى البُنى والأجهزة داخل بنية معيّنة.
إذا لم يمنح المستخدم الأذونات من قبل، استخدِم طريقة
requestPermissions()
في مثيل Home لتشغيل واجهة مستخدم الأذونات ومعالجة النتيجة:
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 لنشر تطبيق باستخدام واجهات برمجة التطبيقات الخاصة بمنصة Home. ليس من الضروري اختبار واجهات برمجة التطبيقات الخاصة بالشاشة الرئيسية واستخدامها.
إذا لم يتم تسجيل تطبيق في Developer Console، ستكون حالته لم يتم التحقّق منه. ننصحك بما يلي لاختبار استخدام واجهات برمجة التطبيقات الخاصة بمنصة Home:
يمكن فقط للمستخدمين المسجَّلين كمستخدمين اختباريين في وحدة تحكّم OAuth منح أذونات للتطبيق، علمًا بأنّ عدد المستخدمين الاختباريين المسموح به هو 100 مستخدم للتطبيق الذي لم يتم التحقّق منه.
سيتمكّن التطبيق الذي لم يتم إثبات ملكيته من الوصول إلى أجهزة من أي أنواع أجهزة متوافقة مع OAuth لواجهات برمجة التطبيقات لمنزل Google (قائمة أنواع الأجهزة في Developer Console). وسيتم منح الإذن لجميع الأجهزة في البنية.
إذا تم تسجيل تطبيق في Developer Console وتمت الموافقة على منحه إذن الوصول إلى نوع جهاز واحد أو أكثر، وتم إكمال عملية إثبات ملكية العلامة التجارية في OAuth، ستكون حالة التطبيق معتمَدة. هذه الحالة مطلوبة لإطلاق تطبيق في مرحلة الإنتاج:
- لم يعُد يتم تطبيق حدود على المستخدمين التجريبيين. يمكن لأي مستخدم منح الإذن للتطبيق.
- يمكن للمستخدم منح الإذن لأنواع الأجهزة التي تمت الموافقة عليها في Developer Console فقط.
بعد إعداد OAuth، يؤدي طلب التطبيق إلى requestPermissions() إلى ظهور مربّعات الحوار التالية:
- يُطلب من المستخدم اختيار حساب Google الذي يريد استخدامه.
- سيُطلب من المستخدم اختيار البنية التي يريد منح التطبيق إذن الوصول إليها.
- بالنسبة إلى التطبيق الذي لم يتم التحقّق منه، تتوفّر للتطبيق جميع أنواع الأجهزة المتوافقة مع واجهات برمجة التطبيقات لمنزل Google.
- بالنسبة إلى التطبيق الذي تم التحقّق منه، يمكن للمستخدم منح الإذن فقط لأنواع الأجهزة التي تمت الموافقة عليها في Developer Console.
- بالنسبة إلى أنواع الأجهزة الحسّاسة التي يمكن للتطبيق الوصول إليها لإدارتها، يمكن للمستخدم حظر الوصول إليها على أساس كل جهاز على حدة. على سبيل المثال، إذا كان لدى المستخدم ثلاثة أقفال، يمكنه منح إذن الوصول إلى قفل واحد فقط من هذه الأقفال.
بعد منح الإذن، يمكن للتطبيق استخدام واجهات برمجة التطبيقات الخاصة بمنصة Home لقراءة حالة الأجهزة في البنية والتحكّم فيها. إذا لم يمنح المستخدم التطبيق إذنًا لنوع جهاز معيّن أو جهاز حسّاس، لن يتمكّن التطبيق من استخدام واجهات برمجة التطبيقات Home للوصول إلى الجهاز أو التحكّم فيه أو تشغيله تلقائيًا.
تغيير الأذونات
لمنح الإذن بالوصول إلى الأجهزة في بنية مختلفة، يمكن تشغيل أداة اختيار الحساب للسماح للمستخدم باختيار حساب Google والبنية التي يريد التبديل إليها. أثناء هذه العملية، ستظهر للمستخدم شاشة طلب الموافقة مرة أخرى، حتى إذا كان قد منح موافقته سابقًا.
يمكن إجراء ذلك من خلال طلب requestPermissions() مرة أخرى مع ضبط العلامة forceLaunch على true:
homeManager.requestPermissions(forceLaunch=true)
تغيير الأذونات باستخدام تلميحات البنية
تتيح ميزة "اقتراح البنية" للتطبيق أن يختار مسبقًا بنية معيّنة أو أن يقصر قائمة البُنى المتاحة عند طلب تغيير تدريجي في أذونات واجهات برمجة التطبيقات الخاصة بمنزل المستخدم. من خلال تمرير مَعلمات البنية إلى طلب التفويض، سيركّز مربّع حوار الأذونات تلقائيًا على البنية المحدّدة، ما يقلّل من المشاكل التي يواجهها المستخدم ويمنع أخطاء الإعداد.
تتم إدارة تلميحات البنية باستخدام فئة البيانات
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
)
إبطال الأذونات
يمكن للمستخدمين إبطال إذن الوصول الذي تم منحه سابقًا باتّباع الخطوات التالية:
من خلال صفحة"حسابي " على Google > البيانات والخصوصية > التطبيقات والخدمات الخارجية سيؤدي ذلك إلى إبطال الرمز المميّز لبروتوكول OAuth الذي تم إصداره عند منح الموافقة الأولية، وإلغاء إذن الوصول إلى أي مثيل من التطبيق كان يستخدمه المستخدم على جميع الأجهزة (الهواتف) والمساحات.
يمكن توجيه المستخدم باستخدام رابط عميق إلى الصفحة الفرعية التطبيقات والخدمات التابعة لجهات خارجية باستخدام مخطّط URL التالي:
https://myaccount.google.com/connections/link?project_number=Cloud project_numberمن خلال صفحة 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 permissions
الأمر
okGoogle
هو أمر على مستوى الجهاز ويمكن استخدامه لتنفيذ أي جهاز في
البنية بشكل آلي، ولكن قد لا يتمكّن تطبيق يستخدم واجهات برمجة تطبيقات Home من الوصول إلى كل جهاز. يوضّح الجدول التالي كيفية فرض الأذونات في مثل هذه الحالات.
| التشغيل الآلي | السمة | فرض الأذونات |
|---|---|---|
| في الساعة 10:00 مساءً، أريد أن يتم بث رسالة مضمونها "حان وقت النوم" على مكبّر صوت غرفة النوم. |
AssistantBroadcastTrait
على الجهاز |
إنشاء عملية مبرمَجة:
|
| في الساعة 10:00 مساءً، أريد أن يتم بث رسالة مضمونها "حان وقت النوم" على جميع الأجهزة |
AssistantBroadcastTrait
على البنية. |
إنشاء عملية مبرمَجة:
|
| في الساعة 10:00 مساءً، "تشغيل بعض الموسيقى" |
AssistantFulfillmentTrait.OkGoogleCommand
|
إنشاء عملية مبرمَجة:
|
| عندما يقول أحد الأشخاص "تشغيل بعض الموسيقى" |
VoiceStarterTrait.OkGoogleEvent
|
إنشاء عملية مبرمَجة:
|
إرشادات في حال ألغى المستخدم الأذونات الكاملة
إذا ألغى المستخدم الأذونات الكاملة، ستتوقف جميع عمليات التشغيل الآلي الحالية عن العمل. في حال إلغاء المستخدم إذن الوصول إلى أجهزة معيّنة، سيتوقف عمل إجراءات التفعيل والشروط والإجراءات المرتبطة بهذه الأجهزة.
في كل مرة يبدأ فيها التطبيق، احرص على التحقّق من أنّ الأذونات لا تزال سارية. إذا تم إبطالها، تأكَّد من إزالة جميع البيانات السابقة، بما في ذلك أي بيانات مخزّنة مؤقتًا في التطبيق.


