این سند باید راهنمای اصلی شما برای استفاده از AMAPI SDK برای اهداف دریافت سیگنال های اعتماد دستگاه باشد.
AMAPI SDK به برنامه شما (که گاهی اوقات ممکن است به عنوان یک برنامه "همراه" از آن یاد کنیم) را قادر می سازد تا به سیگنال های اعتماد دستگاه از برنامه ADP (سیاست دستگاه Android) دسترسی پیدا کند. سپس برنامه شما میتواند از این سیگنالها برای محاسبه وضعیت اعتماد دستگاه استفاده کند و منطق کسبوکار را بهصورت انتخابی اعمال کند.
پیش نیازها
- دسترسی به سیگنال های اعتماد دستگاه برای جلوگیری از استفاده غیرمجاز محدود شده است. برای اطلاعات در مورد نحوه درخواست، به صفحه دسترسی به سیگنال های اعتماد دستگاه بروید.
- Android Enterprise توصیه میکند مجموعه APIهای Play Integrity را در برنامه مشتری خود ادغام کنید و قبل از خواندن و تکیه بر سیگنالهای اعتماد دستگاه، به نتیجه مراجعه کنید. دستگاههایی که بررسیهای API یکپارچگی Play را انجام نمیدهند، نباید مورد اعتماد قرار گیرند، و همچنین نباید به هیچ سیگنالی که از دستگاهی که برای تعیین وضعیت اعتماد بهکار میرود مشتق شده باشد. برای جزئیات بیشتر می توانید به مستندات Play Integrity مراجعه کنید.
با AMAPI SDK در برنامه خود ادغام کنید
برای دسترسی به سیگنال های اعتماد دستگاه، برنامه شما باید با AMAPI SDK ادغام شود. می توانید اطلاعات بیشتری درباره این کتابخانه و نحوه افزودن آن به برنامه خود در راهنمای یکپارچه سازی AMAPI SDK بیابید.
مجوزهای مورد نیاز را اضافه کنید
تعدادی از سیگنالهای بازگردانده شده از Device Trust از Android Enterprise API مستلزم آن است که برنامه همان مجوزی را که در وهله اول برای دسترسی به این اطلاعات لازم است، اعلام کند، به ویژه:
سیگنال | مجوز مورد نیاز |
---|---|
وضعیت شبکه | ACCESS_NETWORK_STATE |
پیچیدگی قفل صفحه | REQUEST_PASSWORD_COMPLEXITY |
اگر این مجوزها در AndroidManifest.xml
برنامه گنجانده نشده باشد، Device Trust از Android Enterprise API PERMISSION_ISSUE
در فراداده سیگنال مربوطه برمی گرداند:
internalDeviceSettings=DeviceSettings{
screenLockComplexity=COMPLEXITY_UNSPECIFIED,
internalScreenLockComplexityMetadata=Metadata{
dataIssues=[
DataIssue{
issueType=PERMISSION_ISSUE,
issueLevel=WARNING,
issueDetails=IssueDetailsCase{none}
}
]
},
برای جزئیات بیشتر به لیست سیگنال های اعتماد دستگاه موجود مراجعه کنید.
مراحل دسترسی به سیگنال های اعتماد دستگاه
برنامههایی که میخواهند به سیگنالهای اعتماد دستگاه دسترسی داشته باشند، باید تأیید کنند که محیط کلاینت بهروز است و در صورت لزوم آن را بهروزرسانی کنند.
مراحل دسترسی به سیگنال های اعتماد دستگاه عبارتند از:
بررسی محیط مشتری
مثال کد زیر نحوه استفاده از getEnvironment
برای خواندن وضعیت فعلی برنامه ADP را نشان می دهد. اگر محیط آماده و بهروز باشد، برنامه شما میتواند یک deviceClient
برای دسترسی به سیگنالهای اعتماد دستگاه ایجاد کند (به سیگنالهای اعتماد دستگاه دسترسی مراجعه کنید).
کاتلین
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) }
جاوا
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 از قبل نصب شده باشد، API بی سر و صدا آن را بدون دخالت کاربر به روز می کند.
اگر برنامه ADP نصب نشده باشد، API از کاربر می خواهد که نصب برنامه ADP را بپذیرد.
امکان ثبت تماس پاسخ برای نظارت بر انتخاب کاربر وجود دارد. برای جزئیات بیشتر به پیگیری تعامل کاربر در طول نصب برنامه ADP مراجعه کنید.
توصیه میکنیم که تماس prepareEnvironment
از یک فرآیند پیشزمینه، در طول جریان UX داخلی انجام شود تا از تعجب کاربر با گفتگوی مودال Install Android Device Policy جلوگیری شود. اگر تماس از یک فرآیند پیشزمینه امکانپذیر نباشد، زیرا این یک جریان وب است و مؤلفه Android فاقد رابط کاربری است، تماس از پسزمینه مجاز است با این شرط که این اتفاق در جریان UX داخلی رخ دهد.
پس از تنظیم صحیح محیط، دسترسی به سیگنال های اعتماد دستگاه امکان پذیر است. به سیگنال های اعتماد دستگاه دسترسی مراجعه کنید.
کاتلین
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()) }
جاوا
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
استفاده کنید.
کاتلین
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()) }
جاوا
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
ردیابی کند:
کاتلین
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 } }
جاوا
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"); } } }
مسائل شناخته شده
در حال حاضر هیچ مشکل شناخته شده ای وجود ندارد.