يجب أن يكون هذا المستند هو دليلك الأساسي لاستخدام حزمة تطوير البرامج (SDK) الخاصة بواجهة برمجة التطبيقات AMAPI لأغراض تلقّي إشارات موثوقية الجهاز.
تتيح حزمة تطوير البرامج (SDK) لواجهة برمجة التطبيقات AMAPI لتطبيقك (الذي قد نشير إليه أحيانًا باسم تطبيق "مساعد") الوصول إلى إشارات موثوقية الجهاز من تطبيق "سياسة جهاز Android" (ADP). ويمكن لتطبيقك بعد ذلك استخدام هذه الإشارات لاحتساب حالة موثوقية الجهاز وتفعيل منطق النشاط التجاري الذي تختاره.
المتطلبات الأساسية
- يتم حظر الوصول إلى إشارات ثقة الجهاز لمنع الاستخدام غير المصرَّح به. للحصول على معلومات حول كيفية تقديم الطلب، انتقِل إلى صفحة الوصول إلى إشارات ثقة الجهاز.
- تنصح Android Enterprise بدمج مجموعة واجهات برمجة التطبيقات Play Integrity في تطبيق العميل والرجوع إلى النتيجة قبل قراءة إشارات موثوقية الجهاز والاعتماد عليها. لا يمكن الوثوق بالأجهزة التي لا تجتاز عمليات التحقّق التي تجريها واجهة برمجة التطبيقات Play Integrity API، ولا بأي إشارات مشتقة من الجهاز المستخدَم لتحديد حالة الثقة. يمكنك الرجوع إلى مستندات Play Integrity لمزيد من التفاصيل.
دمج حزمة تطوير البرامج (SDK) لواجهة برمجة التطبيقات AMAPI في تطبيقك
للوصول إلى إشارات موثوقية الجهاز، يجب أن يتكامل تطبيقك مع حزمة تطوير البرامج لواجهة برمجة التطبيقات AMAPI. يمكنك العثور على مزيد من المعلومات حول هذه المكتبة وكيفية إضافتها إلى تطبيقك في دليل دمج حزمة تطوير البرامج (SDK) لواجهة برمجة التطبيقات AMAPI.
إضافة الأذونات المطلوبة
تتطلّب بعض الإشارات التي يتم عرضها من خلال واجهة برمجة التطبيقات Device Trust from Android Enterprise أن يوضّح التطبيق الإذن نفسه المطلوب للوصول إلى هذه المعلومات في المقام الأول، وخاصةً ما يلي:
إشارة | الإذن المطلوب |
---|---|
حالة الشبكة | ACCESS_NETWORK_STATE |
مستوى صعوبة قفل الشاشة | REQUEST_PASSWORD_COMPLEXITY |
إذا لم يتم تضمين هذه الأذونات في AndroidManifest.xml
للتطبيق، ستعرض واجهة برمجة التطبيقات Device Trust من Android Enterprise القيمة PERMISSION_ISSUE
في البيانات الوصفية للإشارة ذات الصلة:
internalDeviceSettings=DeviceSettings{
screenLockComplexity=COMPLEXITY_UNSPECIFIED,
internalScreenLockComplexityMetadata=Metadata{
dataIssues=[
DataIssue{
issueType=PERMISSION_ISSUE,
issueLevel=WARNING,
issueDetails=IssueDetailsCase{none}
}
]
},
لمزيد من التفاصيل، يُرجى الاطّلاع على قائمة إشارات موثوقية الجهاز المتاحة.
خطوات الوصول إلى إشارات موثوقية الجهاز
يجب أن تتحقّق التطبيقات التي تريد الوصول إلى إشارات موثوقية الجهاز من أنّ بيئة البرنامج محدَّثة، وأن تعمل على تحديثها إذا لزم الأمر.
في ما يلي خطوات الوصول إلى إشارات الثقة بالأجهزة:
التحقّق من بيئة العميل
يوضّح مثال الرمز البرمجي التالي كيفية استخدام getEnvironment
لقراءة الحالة الحالية لتطبيق ADP. ويمكن لتطبيقك بعد ذلك إنشاء deviceClient
للوصول إلى إشارات ثقة الجهاز إذا كانت البيئة جاهزة ومحدّثة (راجِع الوصول إلى إشارات ثقة الجهاز).
Kotlin
import com.google.android.managementapi.common.model.Role import com.google.android.managementapi.device.DeviceClient import com.google.android.managementapi.device.DeviceClientFactory import com.google.android.managementapi.device.model.GetDeviceRequest import com.google.android.managementapi.environment.EnvironmentClient import com.google.android.managementapi.environment.EnvironmentClientFactory import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.INSTALLED import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.NOT_INSTALLED import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.READY import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.Version.UP_TO_DATE import com.google.android.managementapi.environment.model.GetEnvironmentRequest import com.google.android.managementapi.environment.model.PrepareEnvironmentRequest try { val context = applicationContext val roles = listOf(Role.builder().setRoleType(Role.RoleType.IDENTITY_PROVIDER).build()) val request = GetEnvironmentRequest.builder().setRoles(roles).build() val environmentClient = EnvironmentClientFactory.create(context) val environmentResponse = environmentClient.getEnvironment(request) if (environmentResponse.hasAndroidDevicePolicyEnvironment()) { val adpEnvironment = environmentResponse.androidDevicePolicyEnvironment if (adpEnvironment.state == READY && adpEnvironment.version == UP_TO_DATE) { // AMAPI Environment State OK, Version OK. Requesting Device signals.. checkDevice(deviceClient = DeviceClientFactory.create(context)) } else if (adpEnvironment.state == INSTALLED) { // prepareEnvironment should be called, calling // prepareEnvironment won't show the UI prepareEnvironment(context, environmentClient) } else if (adpEnvironment.state == NOT_INSTALLED) { // prepareEnvironment should be called, calling // prepareEnvironment will show the UI prepareEnvironment(context, environmentClient) } } } catch (e: Exception) { Log.e(TAG, "Exception", e) }
Java
import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.INSTALLED; import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.NOT_INSTALLED; import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.READY; import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.Version.UP_TO_DATE; import com.google.android.managementapi.common.model.Role; import com.google.android.managementapi.device.DeviceClient; import com.google.android.managementapi.device.DeviceClientFactory; import com.google.android.managementapi.device.model.Device; import com.google.android.managementapi.device.model.GetDeviceRequest; import com.google.android.managementapi.environment.EnvironmentClient; import com.google.android.managementapi.environment.EnvironmentClientFactory; import com.google.android.managementapi.environment.model.Environment; import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment; import com.google.android.managementapi.environment.model.GetEnvironmentRequest; import com.google.android.managementapi.environment.model.PrepareEnvironmentRequest; import com.google.android.managementapi.environment.model.PrepareEnvironmentResponse; try { Context context = getApplicationContext(); ImmutableListroles = new ImmutableList.Builder () .add(Role.builder() .setRoleType(Role.RoleType.IDENTITY_PROVIDER) .build()) .build(); EnvironmentClient environmentClient = EnvironmentClientFactory.create(context); GetEnvironmentRequest request = GetEnvironmentRequest.builder() .setRoles(roles) .build(); ListenableFuture getEnvironmentFuture = environmentClient.getEnvironmentAsync(request); Futures.addCallback(getEnvironmentFuture, new FutureCallback<>() { @Override public void onSuccess(Environment environment) { AndroidDevicePolicyEnvironment adpEnvironment = environment.getAndroidDevicePolicyEnvironment(); AndroidDevicePolicyEnvironment.State state = adpEnvironment.getState(); AndroidDevicePolicyEnvironment.Version version = adpEnvironment.getVersion(); if (state == READY && version == UP_TO_DATE) { // AMAPI Environment State OK, Version OK. Requesting Device signals.. DeviceClient deviceClient = DeviceClientFactory.create(context); checkDevice(deviceClient); } else if (state == INSTALLED) { // prepareEnvironment should be called, calling // prepareEnvironment won't show the UI prepareEnvironment(context, environmentClient); } else if (state == NOT_INSTALLED) { // prepareEnvironment should be called, calling // prepareEnvironment will show the UI prepareEnvironment(context, environmentClient); } } @Override public void onFailure(Throwable t) { Log.d(TAG, t.toString()); } }, MoreExecutors.directExecutor()); } catch (Exception e) { Log.d(TAG, e.toString()); }
إذا كان تطبيق ADP مثبَّتًا ولكنّه ليس محدَّثًا، يجب أن يستدعي تطبيقك الدالة
prepareEnvironment
لتحديث تطبيق ADP تلقائيًا بدون تدخل المستخدم.
إذا لم يكن تطبيق ADP مثبَّتًا، يمكن لتطبيقك استدعاء prepareEnvironment
لطلب تثبيت تطبيق ADP من المستخدم. راجِع إعداد بيئة العميل.
إعداد بيئة العميل
إذا كان تطبيق ADP مثبَّتًا من قبل، ستعمل واجهة برمجة التطبيقات على تحديثه تلقائيًا بدون أي تدخل من المستخدم.
إذا لم يكن تطبيق ADP مثبّتًا، ستطلب واجهة برمجة التطبيقات من المستخدم قبول تثبيت تطبيق ADP.
من الممكن تسجيل دالة ردّ لتتبُّع اختيار المستخدم. راجِع مقالة تتبُّع تفاعل المستخدم أثناء تثبيت تطبيق ADP للحصول على تفاصيل إضافية.
ننصحك بتنفيذ طلب prepareEnvironment
من عملية تعمل في المقدّمة، وذلك أثناء مسار تجربة المستخدم عند الإعداد لتجنُّب مفاجأة المستخدم بعرض مربّع الحوار المشروط تثبيت تطبيق "سياسة أمان Android".
إذا لم يكن من الممكن إجراء المكالمة من عملية في المقدّمة، لأنّ هذا إجراء على الويب ولا يتضمّن مكوّن Android أي واجهة مستخدم، يُسمح بإجراء المكالمة من الخلفية بشرط أن يتم ذلك أثناء عملية إعداد تجربة المستخدم.
بعد إعداد البيئة بشكل صحيح، يمكن الوصول إلى إشارات ثقة الجهاز. اطّلِع على الوصول إلى إشارات "موثوقية الجهاز".
Kotlin
try { val myNotificationReceiverService = ComponentName( context, MyNotificationReceiverService::class.java ) val roles = listOf(Role.builder().setRoleType(Role.RoleType.IDENTITY_PROVIDER).build()) val request = PrepareEnvironmentRequest.builder().setRoles(roles).build() val response = environmentClient.prepareEnvironment(request, myNotificationReceiverService) val environment = response.environment val adpEnvironment = environment.androidDevicePolicyEnvironment val state = adpEnvironment.state val version = adpEnvironment.version if (state == READY && version == UP_TO_DATE) { // Environment is prepared, access device posture signals using // DeviceClient. checkDevice(deviceClient = DeviceClientFactory.create(context)) } else { // The prepareEnvironment call failed to prepare Log.w( TAG, "AMAPI environment was not ready: " + state + " - " + version ) } } catch (e: java.lang.Exception) { Log.d(TAG, e.toString()) }
Java
try { ComponentName myNotificationReceiverService = new ComponentName( context, MyNotificationReceiverService.class ); ImmutableListroles = new ImmutableList.Builder () .add(Role.builder() .setRoleType(Role.RoleType.IDENTITY_PROVIDER) .build()) .build(); PrepareEnvironmentRequest request = PrepareEnvironmentRequest.builder() .setRoles(roles) .build(); ListenableFuture environmentFuture = environmentClient.prepareEnvironmentAsync( request, myNotificationReceiverService ); Futures.addCallback(environmentFuture, new FutureCallback<>() { @Override public void onSuccess(PrepareEnvironmentResponse response) { Environment environment = response.getEnvironment(); AndroidDevicePolicyEnvironment adpEnvironment = environment.getAndroidDevicePolicyEnvironment(); AndroidDevicePolicyEnvironment.State state = adpEnvironment.getState(); AndroidDevicePolicyEnvironment.Version version = adpEnvironment.getVersion(); if (state == READY && version == UP_TO_DATE) { // AMAPI Environment State OK, Version OK. Requesting Device signals.. DeviceClient deviceClient = DeviceClientFactory.create(context); checkDevice(deviceClient); } else { // The prepareEnvironment call failed to prepare Log.w( TAG, "AMAPI environment was not ready: " + adpEnvironment.getState() + " - " + adpEnvironment.getVersion() ); } } @Override public void onFailure(@NonNull Throwable t) { // Handle the error Log.d(TAG, "AMAPI response did not contain an ADP environment"); } }, MoreExecutors.directExecutor()); } catch (Exception e) { Log.d(TAG, e.toString()); }
الوصول إلى إشارات الثقة في الجهاز
وضع الجهاز.للوصول إلى إشارات موثوقية الجهاز التي تهمّك، يمكنك استخدام مثيل deviceClient
الذي تم عرضه في الخطوة السابقة لطلب العنصر Device
.
Kotlin
try { kotlin.runCatching { deviceClient.getDeviceAwait(GetDeviceRequest.getDefaultInstance()) }.onFailure { t -> Log.d(TAG, t.toString()) }.onSuccess { device -> // Access device posture signals available in device val deviceString = device.toString() Log.d(TAG, deviceString) } } catch (e: java.lang.Exception) { Log.d(TAG, e.toString()) }
Java
try { ListenableFuturedeviceFuture = deviceClient.getDevice(GetDeviceRequest.getDefaultInstance()); Futures.addCallback(deviceFuture, new FutureCallback () { @Override public void onSuccess(Device device) { // Access device posture signals available in device String deviceString = device.toString(); Log.d(TAG, deviceString); } @Override public void onFailure(Throwable t) { Log.d(TAG, Log.d(TAG, t.toString()); } }, MoreExecutors.directExecutor()); } catch (Exception e) { Log.d(TAG, e.toString()); }
تتبُّع تفاعل المستخدم أثناء تثبيت تطبيق ADP
إذا كان الجهاز بحاجة إلى تثبيت تطبيق ADP أثناء prepareEnvironment
، يمكن لتطبيقك تتبُّع تفاعل المستخدم من خلال تنفيذ NotificationReceiverService
لتلقّي الإشعارات التي تتجاوز getPrepareEnvironmentListener
:
Kotlin
import android.util.Log import com.google.android.managementapi.environment.EnvironmentListener import com.google.android.managementapi.environment.model.EnvironmentEvent.EventCase.Kind.ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED import com.google.android.managementapi.environment.model.EnvironmentEvent import com.google.android.managementapi.notification.NotificationReceiverService class MyNotificationReceiverService : NotificationReceiverService() { override fun getPrepareEnvironmentListener(): EnvironmentListener { return MyEnvironmentListener() } } class MyEnvironmentListener : EnvironmentListener { override fun onEnvironmentEvent( event: EnvironmentEvent ) { if (event.event.kind == ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED) { Log.d(TAG, "User provided install consent") } else { Log.d(TAG, "User rejected install consent") } } companion object { private val TAG: String = MyEnvironmentListener::class.java.simpleName } }
Java
import static com.google.android.managementapi.environment.model.EnvironmentEvent.EventCase.Kind.ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED; import android.util.Log; import androidx.annotation.NonNull; import com.google.android.managementapi.environment.EnvironmentListener; import com.google.android.managementapi.environment.model.EnvironmentEvent; import com.google.android.managementapi.notification.NotificationReceiverService; class MyNotificationReceiverService extends NotificationReceiverService { @NonNull @Override protected EnvironmentListener getPrepareEnvironmentListener() { return new MyEnvironmentListener(); } } class MyEnvironmentListener implements EnvironmentListener { final private String TAG = MyEnvironmentListener.class.getSimpleName(); @Override public void onEnvironmentEvent(EnvironmentEvent event) { if (event.getEvent().getKind() == ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED) { Log.d(TAG, "User provided install consent"); } else { Log.d(TAG, "User rejected install consent"); } } }
المشاكل المعروفة
ليس هناك أي مشاكل معروفة في الوقت الحالي.