Questo documento deve essere la tua guida principale per l'utilizzo dell'SDK AMAPI ai fini della ricezione degli indicatori di attendibilità del dispositivo.
L'SDK AMAPI consente alla tua applicazione (che a volte potremmo chiamare app "complementare") di accedere agli indicatori di affidabilità del dispositivo dall'app ADP (Android Device Policy). La tua app può quindi utilizzare questi indicatori per calcolare lo stato di affidabilità del dispositivo e implementare la logica di business scelta.
Prerequisiti
- L'accesso agli indicatori di attendibilità del dispositivo è limitato per impedire l'utilizzo non autorizzato. Per informazioni su come fare domanda, vai alla pagina Accesso agli indicatori di attendibilità del dispositivo.
- Android Enterprise consiglia di integrare la suite di API Play Integrity nell'applicazione client e di fare riferimento al risultato prima di leggere e affidarsi agli indicatori di attendibilità del dispositivo. I dispositivi che non superano i controlli dell'API Play Integrity non devono essere considerati attendibili, né gli indicatori derivati dal dispositivo utilizzati per determinare il livello di attendibilità. Per ulteriori dettagli, consulta la documentazione di Play Integrity.
Integrare l'SDK AMAPI nell'applicazione
Per accedere agli indicatori di attendibilità del dispositivo, la tua applicazione deve integrarsi con l'SDK AMAPI. Puoi trovare ulteriori informazioni su questa libreria e su come aggiungerla alla tua applicazione nella guida all'integrazione dell'SDK AMAPI.
Aggiungere le autorizzazioni richieste
Alcuni degli indicatori restituiti dall'API Device Trust di Android Enterprise richiedono che l'app dichiari la stessa autorizzazione necessaria per accedere a queste informazioni in primo luogo, in particolare:
Indicatore | Autorizzazione obbligatoria |
---|---|
Stato rete | ACCESS_NETWORK_STATE |
Complessità del blocco schermo | REQUEST_PASSWORD_COMPLEXITY |
Se queste autorizzazioni non sono incluse nel AndroidManifest.xml
dell'app, l'API Device Trust di Android Enterprise restituirà PERMISSION_ISSUE
nei metadati del segnale correlato:
internalDeviceSettings=DeviceSettings{
screenLockComplexity=COMPLEXITY_UNSPECIFIED,
internalScreenLockComplexityMetadata=Metadata{
dataIssues=[
DataIssue{
issueType=PERMISSION_ISSUE,
issueLevel=WARNING,
issueDetails=IssueDetailsCase{none}
}
]
},
Per ulteriori dettagli, consulta l'elenco degli indicatori di Device Trust disponibili.
Passaggi per accedere agli indicatori di attendibilità del dispositivo
Le applicazioni che vogliono accedere agli indicatori di attendibilità del dispositivo devono verificare che l'ambiente client sia aggiornato e aggiornarlo se necessario.
I passaggi per accedere agli indicatori di attendibilità del dispositivo sono:
- Verificare l'ambiente client
- Prepara l'ambiente client
- Accedere agli indicatori di attendibilità del dispositivo
Verifica l'ambiente client
Il seguente esempio di codice mostra come utilizzare getEnvironment
per leggere lo stato attuale dell'app ADP. La tua applicazione può quindi creare un deviceClient
per accedere agli indicatori di attendibilità del dispositivo se l'ambiente è pronto e aggiornato (vedi Accedere agli indicatori di attendibilità del dispositivo).
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()); }
Se l'app ADP è installata ma non aggiornata, l'applicazione deve chiamare
prepareEnvironment
per aggiornare automaticamente l'app ADP senza intervento dell'utente.
Se l'app ADP non è installata, la tua applicazione può chiamare prepareEnvironment
per chiedere all'utente di installare l'app ADP. Vedi
Preparare l'ambiente client.
Preparare l'ambiente client
Se l'app ADP è già installata, l'API la aggiornerà automaticamente senza intervento dell'utente.
Se l'app ADP non è installata, l'API chiederà all'utente di accettare l'installazione dell'app ADP.
È possibile registrare un callback per monitorare la scelta dell'utente. Per ulteriori dettagli, consulta Monitorare l'interazione degli utenti durante l'installazione dell'app ADP.
Ti consigliamo di effettuare la chiamata prepareEnvironment
da un processo in primo piano durante il flusso UX di onboarding per evitare di sorprendere l'utente con la finestra di dialogo modale Installa Android Device Policy.
Se la chiamata da un processo in primo piano non è possibile, perché si tratta di un flusso web
e il componente Android non ha un'interfaccia utente, la chiamata da background è consentita con
il requisito che avvenga durante il flusso UX di onboarding.
Una volta configurato correttamente l'ambiente, è possibile accedere agli indicatori di attendibilità del dispositivo. Consulta Accedere agli indicatori di attendibilità del dispositivo.
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()); }
Accedere agli indicatori di attendibilità del dispositivo
Per accedere agli indicatori di attendibilità del dispositivo che ti interessano, puoi utilizzare l'istanza deviceClient
visualizzata nel passaggio precedente per richiedere l'oggetto 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()); }
Monitorare l'interazione dell'utente durante l'installazione dell'app ADP
Se il dispositivo deve installare l'app ADP durante prepareEnvironment
, la tua applicazione può monitorare l'interazione dell'utente implementando un NotificationReceiverService
per ricevere notifiche che ignorano 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"); } } }
Problemi noti
Al momento non sono noti problemi.