Guida a Microsoft Intune App SDK per sviluppatori di AndroidMicrosoft Intune App SDK for Android developer guide

Nota

Si consiglia di leggere prima Panoramica di Intune App SDK, che illustra le attuali funzionalità dell'SDK e descrive come preparare l'integrazione in ogni piattaforma supportata.You might want to first read the Intune App SDK overview, which covers the current features of the SDK and describes how to prepare for integration on each supported platform.

Microsoft Intune App SDK per Android consente di integrare i criteri di protezione delle app di Intune, noti anche come criteri APP o MAM, nell'app Android nativa.The Microsoft Intune App SDK for Android lets you incorporate Intune app protection policies (also known as APP or MAM policies) into your native Android app. Un'applicazione con supporto per Intune è integrata con Intune App SDK.An Intune-enlightened application is one that is integrated with the Intune App SDK. Gli amministratori di Intune possono distribuire facilmente i criteri di protezione delle app nell'app con supporto per Intune quando Intune gestisce attivamente l'app.Intune administrators can easily deploy app protection policies to your Intune-enlightened app when Intune actively manages the app.

Contenuto dell'SDKWhat's in the SDK

Intune App SDK è costituito dai file seguenti:The Intune App SDK consists of the following files:

  • Microsoft.Intune.MAM.SDK.aar: componenti dell'SDK, ad eccezione dei file JAR Support.V4 e Support.V7.Microsoft.Intune.MAM.SDK.aar: The SDK components, with the exception of the Support.V4 and Support.V7 JAR files. Questo file può essere usato al posto dei singoli componenti se il sistema di compilazione supporta i file AAR.This file can be used in place of the individual components if your build system supports AAR files.
  • Microsoft.Intune.MAM.SDK.Support.v4.jar: interfacce necessarie per abilitare MAM nelle app che usano la libreria di supporto Android v4.Microsoft.Intune.MAM.SDK.Support.v4.jar: The interfaces necessary to enable MAM in apps that use the Android v4 support library. Le app che richiedono questo supporto devono fare riferimento al file JAR direttamente.Apps that need this support must reference the JAR file directly.
  • Microsoft.Intune.MAM.SDK.Support.v7.jar: interfacce necessarie per abilitare MAM nelle app che usano la libreria di supporto Android v7.Microsoft.Intune.MAM.SDK.Support.v7.jar: The interfaces necessary to enable MAM in apps that use the Android v7 support library. Le app che richiedono questo supporto devono fare riferimento al file JAR direttamente.Apps that need this support must reference the JAR file directly.
  • proguard.txt: contiene le regole ProGuard che devono essere applicate in caso di compilazione con ProGuard.proguard.txt: Contains ProGuard rules which must be applied if building with ProGuard.
  • CHANGELOG.txt: fornisce un record delle modifiche apportate in ogni versione dell'SDK.CHANGELOG.txt: Provides a record of changes made in each SDK version.
  • THIRDPARTYNOTICES.TXT: comunicazione di attribuzione che riconosce la presenza di codice OSS e/o di terze parti che verrà compilato nell'app.THIRDPARTYNOTICES.TXT: An attribution notice that acknowledges third-party and/or OSS code that will be compiled into your app.

Se il sistema di compilazione non supporta i file AAR, è possibile usare i file seguenti al posto di Microsoft.Intune.MAM.SDK.aar.If your build system does not support AAR files, you may use the following files in place of Microsoft.Intune.MAM.SDK.aar.

  • Microsoft.Intune.MAM.SDK.jar: interfacce necessarie per abilitare MAM e l'interoperabilità con l'app Portale aziendale Intune.Microsoft.Intune.MAM.SDK.jar: The interfaces necessary to enable MAM and interoperability with the Intune Company Portal app. Le app devono specificare questo file come riferimento alla libreria Android.Apps must specify it as an Android library reference.
  • Directory res: risorse (come le stringhe) su cui è basato l'SDK.The res directory: The resources (like strings) on which the SDK relies.
  • AndroidManifest.xml: punti di ingresso e requisiti della libreria.AndroidManifest.xml: Entry points and the library requirements.

RequisitiRequirements

Intune App SDK è un progetto Android compilato.The Intune App SDK is a compiled Android project. Di conseguenza, per lo più non è interessato dalla versione di Android usata dall'app per le versioni delle API minime o di destinazione.As a result, it is largely unaffected by the version of Android that the app uses for its minimum or target API versions. L'SDK supporta le API da Android 14 (Android 4.0+) ad Android 25 (Android 7.1).The SDK supports Android API 14 (Android 4.0+) through Android API 25 (Android 7.1).

App Portale aziendaleCompany Portal app

Intune App SDK per Android richiede la presenza dell'app Portale aziendale nel dispositivo per abilitare i criteri di protezione delle app.The Intune App SDK for Android relies on the presence of the Company Portal app on the device to enable app protection policies. Il Portale aziendale recupera i criteri di protezione delle app dal servizio Intune.The Company Portal retrieves app protection policies from the Intune service. Al momento dell'inizializzazione, l'app carica i criteri e il codice per applicare i criteri dal Portale aziendale.When the app initializes, it loads policy and code to enforce that policy from the Company Portal.

Nota

Quando l'app Portale aziendale non è presente nel dispositivo, un'app con supporto per Intune si comporta analogamente a una normale app che non supporta i criteri di protezione delle app di Intune.When the Company Portal app is not on the device, an Intune-enlightened app behaves the same as a normal app that does not support Intune app protection policies.

Per la protezione delle app senza registrazione del dispositivo, non è richiesta la registrazione del dispositivo con l'app Portale aziendale.For app protection without device enrollment, the user is not required to enroll the device by using the Company Portal app.

Integrazione dell'SDKSDK Integration

Integrazione della compilazioneBuild integration

Intune App SDK è una libreria Android standard senza dipendenze esterne.The Intune App SDK is a standard Android library with no external dependencies. Microsoft.Intune.MAM.SDK.jar contiene sia le interfacce necessarie per abilitare i criteri di protezione delle app che il codice per l'interoperabilità con l'app Portale aziendale Microsoft Intune.Microsoft.Intune.MAM.SDK.jar contains both the interfaces necessary for an app protection policy enablement and the code necessary to interoperate with the Microsoft Intune Company Portal app.

È necessario specificare Microsoft.Intune.MAM.SDK.jar come riferimento alla libreria Android.Microsoft.Intune.MAM.SDK.jar must be specified as an Android library reference. A tale scopo, aprire il progetto di app in Android Studio, passare a File > New > New module (File > Nuovo > Nuovo modulo) e selezionare Import .JAR/.AAR Package (Importa pacchetto JAR/AAR).To do this, open your app project in Android Studio and go to File > New > New module and select Import .JAR/.AAR Package. Selezionare il pacchetto di archivio Android Microsoft.Intune.MAM.SDK.aar.Select our Android archive package Microsoft.Intune.MAM.SDK.aar.

Microsoft.Intune.MAM.SDK.Support.v4 e Microsoft.Intune.MAM.SDK.Support.v7 contengono inoltre varianti di Intune, rispettivamente di android.support.v4 e android.support.v7.Additionally, Microsoft.Intune.MAM.SDK.Support.v4 and Microsoft.Intune.MAM.SDK.Support.v7 contain Intune variants of android.support.v4 and android.support.v7 respectively. Questi file sono integrati in Microsoft.Intune.MAM.SDK.aar nel caso in cui non si voglia includere le librerie di supporto in un'app.They are not built into Microsoft.Intune.MAM.SDK.aar in case an app does not want to include the support libraries. Si tratta di file JAR standard invece che di progetti di libreria Android.They are standard JAR files instead of Android library projects.

ProGuardProGuard

Se viene usato ProGuard (o qualsiasi altro meccanismo di compattazione/offuscamento) come passaggio di compilazione, è necessario escludere le classi di Intune SDK.If ProGuard (or any other shrinking/obfuscation mechanism) is used as a build step, Intune SDK classes must be excluded. Per ProGuard ciò è possibile includendo le regole dal file proguard.txt distribuito con l'SDK.For ProGuard, this can be accomplished by including the rules from the proguard.txt file distributed with the SDK.

Le librerie ADAL (Azure Active Directory Authentication Library) possono avere le proprie restrizioni per ProGuard.The Azure Active Directory Authentication Libraries (ADAL) may have its own ProGuard restrictions. Se l'app integra ADAL, è necessario seguire la documentazione di ADAL in merito a tali restrizioni.If your app integrates ADAL, you must follow the ADAL documentation on these restrictions.

Punti di ingressoEntry points

La libreria ADAL (Azure Active Directory Authentication Library) richiede queste autorizzazioni per eseguire l'autenticazione negoziata.The Azure Active Directory Authentication Library (ADAL) requires these permissions to perform brokered authentication. Se queste autorizzazioni non vengono concesse all'app o vengono revocate dall'utente, verranno disabilitati i flussi di autenticazione che richiedono il broker (l'app Portale aziendale).If these permissions are not granted to the app or are revoked by the user, authentication flows that require the broker (the Company Portal app) will be disabled.

Intune App SDK richiede modifiche del codice sorgente di un'app per abilitare i criteri di protezione delle app di Intune.The Intune App SDK requires changes to an app's source code to enable Intune app protection policies. A questo scopo, vengono sostituite le classi base di Android con le classi base di Intune equivalenti, che hanno nomi con il prefisso MAM.This is done through the replacement of the Android base classes with equivalent Intune base classes, whose names have the prefix MAM. Le classi dell'SDK si trovano tra la classe base per Android e la versione derivata dell'app di tale classe.The SDK classes live between the Android base class and the app's own derived version of that class. Usando un'attività come esempio, la gerarchia di ereditarietà risultante ha un aspetto simile a questa: Activity > MAMActivity > AppSpecificActivity.Using an activity as an example, you end up with an inheritance hierarchy that looks like: Activity > MAMActivity > AppSpecificActivity.

Ad esempio, quando AppSpecificActivity interagisce con il relativo padre (ad esempio, chiamando super.onCreate()), MAMActivity è la superclasse.For example, when AppSpecificActivity interacts with its parent (for example, calling super.onCreate()), MAMActivity is the super class.

Le app Android tipiche hanno una modalità singola e possono accedere al sistema tramite l'oggetto Context.Typical Android apps have a single mode and can access the system through their Context object. Le app con Intune App SDK integrato, invece, hanno due modalità.Apps that have integrated the Intune App SDK, on the other hand, have dual modes. Continuano ad accedere al sistema tramite l'oggetto Context,These apps continue to access the system through the Context object. ma, a seconda della classe base Activity usata, l'oggetto Context viene fornito da Android oppure viene sottoposto a multiplexing avanzato tra una visualizzazione con restrizioni del sistema e l'oggetto Context fornito da Android.Depending on the base Activity used, the Context object will be provided by Android or will intelligently multiplex between a restricted view of the system and the Android-provided Context. Quando si deriva da uno dei punti di ingresso MAM, è consigliabile usare l'oggetto Context come di consueto, ad esempio nell'avvio di classi Activity e nell'uso di PackageManager.After you derive from one of the MAM entry points, it's safe to use Context as you would normally -- for example, starting Activity classes and using PackageManager.

Sostituire classi, metodi e attività con gli equivalenti MAMReplace classes, methods, and activities with their MAM equivalent

Le classi base di Android devono essere sostituite con il rispettivo equivalente MAM.Android base classes must be replaced with their respective MAM equivalents. A questo scopo, trovare tutte le istanze delle classi elencate nella tabella seguente e sostituirle con l'equivalente di Intune App SDK.To do so, find all instances of the classes listed in the following table and replace them with the Intune App SDK equivalent.

Classe base AndroidAndroid base class Sostituzione di Intune App SDKIntune App SDK replacement
android.app.Activityandroid.app.Activity MAMActivityMAMActivity
android.app.ActivityGroupandroid.app.ActivityGroup MAMActivityGroupMAMActivityGroup
android.app.AliasActivityandroid.app.AliasActivity MAMAliasActivityMAMAliasActivity
android.app.Applicationandroid.app.Application MAMApplicationMAMApplication
android.app.DialogFragmentandroid.app.DialogFragment MAMDialogFragmentMAMDialogFragment
android.app.ExpandableListActivityandroid.app.ExpandableListActivity MAMExpandableListActivityMAMExpandableListActivity
android.app.Fragmentandroid.app.Fragment MAMFragmentMAMFragment
android.app.IntentServiceandroid.app.IntentService MAMIntentServiceMAMIntentService
android.app.LauncherActivityandroid.app.LauncherActivity MAMLauncherActivityMAMLauncherActivity
android.app.ListActivityandroid.app.ListActivity MAMListActivityMAMListActivity
android.app.NativeActivityandroid.app.NativeActivity MAMNativeActivityMAMNativeActivity
android.app.PendingIntentandroid.app.PendingIntent MAMPendingIntent (vedere le note sotto)MAMPendingIntent (see notes below)
android.app.Serviceandroid.app.Service MAMServiceMAMService
android.app.TabActivityandroid.app.TabActivity MAMTabActivityMAMTabActivity
android.app.TaskStackBuilderandroid.app.TaskStackBuilder MAMTaskStackBuilderMAMTaskStackBuilder
android.app.backup.BackupAgentandroid.app.backup.BackupAgent MAMBackupAgentMAMBackupAgent
android.app.backup.BackupAgentHelperandroid.app.backup.BackupAgentHelper MAMBackupAgentHelperMAMBackupAgentHelper
android.app.backup.FileBackupHelperandroid.app.backup.FileBackupHelper MAMFileBackupHelperMAMFileBackupHelper
android.app.backup.SharePreferencesBackupHelperandroid.app.backup.SharePreferencesBackupHelper MAMSharedPreferencesBackupHelperMAMSharedPreferencesBackupHelper
android.content.BroadcastReceiverandroid.content.BroadcastReceiver MAMBroadcastReceiverMAMBroadcastReceiver
android.content.ContentProviderandroid.content.ContentProvider MAMContentProviderMAMContentProvider
android.os.Binderandroid.os.Binder MAMBinder (necessaria solo se il binder non viene generato da un'interfaccia AIDL (Android Interface Definition Language))MAMBinder (Only necessary if the Binder is not generated from an Android Interface Definition Language (AIDL) interface)
android.provider.DocumentsProviderandroid.provider.DocumentsProvider MAMDocumentsProviderMAMDocumentsProvider
android.preference.PreferenceActivityandroid.preference.PreferenceActivity MAMPreferenceActivityMAMPreferenceActivity

Microsoft.Intune.MAM.SDK.Support.v4.jar:Microsoft.Intune.MAM.SDK.Support.v4.jar:

MAM di Intune - Classe AndroidAndroid Class Intune MAM Sostituzione di Intune App SDKIntune App SDK replacement
android.support.v4.app.DialogFragmentandroid.support.v4.app.DialogFragment MAMDialogFragmentMAMDialogFragment
android.support.v4.app.FragmentActivityandroid.support.v4.app.FragmentActivity MAMFragmentActivityMAMFragmentActivity
android.support.v4.app.Fragmentandroid.support.v4.app.Fragment MAMFragmentMAMFragment
android.support.v4.app.TaskStackBuilderandroid.support.v4.app.TaskStackBuilder MAMTaskStackBuilderMAMTaskStackBuilder
android.support.v4.content.FileProviderandroid.support.v4.content.FileProvider MAMFileProviderMAMFileProvider

Microsoft.Intune.MAM.SDK.Support.v7.jar:Microsoft.Intune.MAM.SDK.Support.v7.jar:

Classe AndroidAndroid Class Sostituzione di Intune App SDKIntune App SDK replacement
android.support.v7.app.ActionBarActivityandroid.support.v7.app.ActionBarActivity MAMActionBarActivityMAMActionBarActivity

Metodi rinominatiRenamed Methods

In molti casi, un metodo disponibile nella classe Android è stato contrassegnato come finale nella classe sostitutiva MAM.In many cases, a method available in the Android class has been marked as final in the MAM replacement class. In questo caso, la classe sostitutiva MAM fornisce un metodo denominato in modo analogo (in genere con suffisso MAM), che deve essere sostituito al suo posto.In this case, the MAM replacement class provides a similarly named method (generally suffixed with MAM) that you should override instead. Ad esempio, quando si deriva da MAMActivity, invece di sostituire onCreate() e chiamare super.onCreate(), la classe Activity deve sostituire onMAMCreate() e chiamare super.onMAMCreate().For example, when deriving from MAMActivity, instead of overriding onCreate() and calling super.onCreate(), Activity must override onMAMCreate() and call super.onMAMCreate(). Il compilatore Java deve applicare le restrizioni finali per impedire la sostituzione accidentale del metodo originale invece dell'equivalente MAM.The Java compiler should enforce the final restrictions to prevent accidental override of the original method instead of the MAM equivalent.

PendingIntentPendingIntent

Invece di PendingIntent.get*, è necessario usare il metodo MAMPendingIntent.get*.Instead of PendingIntent.get*, you must use the MAMPendingIntent.get* method. Successivamente, è possibile usare la classe PendingIntent risultante come di consueto.After this, you can use the resultant PendingIntent as usual.

Sostituzioni per il manifestoManifest Replacements

Si noti che potrebbe essere necessario eseguire alcune delle sostituzioni di classi indicate in precedenza nel file manifesto e nel codice Java.Please note that it may be necessary to perform some of the above class replacements in the manifest as well as in Java code. Importante:Of special note:

  • I riferimenti del manifesto a android.support.v4.content.FileProvider devono essere sostituiti con com.microsoft.intune.mam.client.support.v4.content.MAMFileProvider.Manifest references to android.support.v4.content.FileProvider must be replaced with com.microsoft.intune.mam.client.support.v4.content.MAMFileProvider.
  • Se l'applicazione non ha la necessità di una propria classe derivata dell'applicazione, com.microsoft.intune.mam.client.app.MAMApplication deve essere impostato come il nome della classe dell'applicazione usato nel manifesto.If your application does not have a need for its own derived Application class, com.microsoft.intune.mam.client.app.MAMApplication must be set as the name of the Application class used in the manifest.

Autorizzazioni dell'SDKSDK permissions

Intune App SDK richiede tre autorizzazioni di sistema Android per le app che lo integrano:The Intune App SDK requires three Android system permissions on apps that integrate it:

  • android.permission.GET_ACCOUNTS (richiesta in fase di esecuzione se necessario)android.permission.GET_ACCOUNTS (requested at runtime if required)

  • android.permission.MANAGE_ACCOUNTS

  • android.permission.USE_CREDENTIALS

La libreria ADAL (Azure Active Directory Authentication Library) richiede queste autorizzazioni per eseguire l'autenticazione negoziata.The Azure Active Directory Authentication Library (ADAL) requires these permissions to perform brokered authentication. Se queste autorizzazioni non vengono concesse all'app o vengono revocate dall'utente, verranno disabilitati i flussi di autenticazione che richiedono il broker (l'app Portale aziendale).If these permissions are not granted to the app or are revoked by the user, authentication flows that require the broker (the Company Portal app) will be disabled.

RegistrazioneLogging

La registrazione deve essere inizializzata presto per ottenere il massimo valore dai dati registrati.Logging should be initialized early to get the most value out of logged data. Application.onMAMCreate() rappresenta in genere la posizione migliore per inizializzare la registrazione.Application.onMAMCreate() is typically the best place to initialize logging.

Per ricevere i log MAM nell'app, creare un gestore Java e aggiungerlo a MAMLogHandlerWrapper.To receive MAM logs in your app, create a Java Handler and add it to the MAMLogHandlerWrapper. Ciò consentirà di richiamare publish() sul gestore dell'applicazione per ogni messaggio di log.This will invoke publish() on the application handler for every log message.

/**
 * Global log handler that enables fine grained PII filtering within MAM logs.  
 *
 * To start using this you should build your own log handler and add it via
 * MAMComponents.get(MAMLogHandlerWrapper.class).addHandler(myHandler, false);  
 *
 * You may also remove the handler entirely via
 * MAMComponents.get(MAMLogHandlerWrapper.class).removeHandler(myHandler);
 */
public interface MAMLogHandlerWrapper {
    /**
     * Add a handler, PII can be toggled.
     *
     * @param handler handler to add.
     * @param wantsPII if PII is desired in the logs.    
     */
    void addHandler(final Handler handler, final boolean wantsPII);

    /**
     * Remove a handler.
     *
     * @param handler handler to remove.
     */
    void removeHandler(final Handler handler);
}

Abilitare le funzionalità che richiedono la partecipazione dell'appEnable features that require app participation

Alcuni criteri di protezione delle app non possono essere implementati direttamente dall'SDK.There are several app protection policies the SDK cannot implement on its own. L'app può controllare il suo comportamento per queste funzionalità usando varie API disponibili nell'interfaccia di AppPolicy seguente.The app can control its behavior to achieve these features by using several APIs that you can find in the following AppPolicy interface. Per recuperare un'istanza AppPolicy, usare MAMPolicyManager.getPolicy.To retrieve an AppPolicy instance, use MAMPolicyManager.getPolicy.

/**
 * External facing application policies.
 */
public interface AppPolicy {

/**
 * Restrict where an app can save personal data.
 * This function is now deprecated. Please use getIsSaveToLocationAllowed(SaveLocation, String) instead
 * @return True if the app is allowed to save to personal data stores; false otherwise.
 */
@Deprecated
boolean getIsSaveToPersonalAllowed();

/**
 * Check if policy prohibits saving to a content provider location.
 *
 * @param location
 *            a content URI to check
 * @return True if location is not a content URI or if policy does not prohibit saving to the content location.
 */
boolean getIsSaveToLocationAllowed(Uri location);

/**
 * Determines if the SaveLocation passed in can be saved to by the username associated with the cloud service.
 *
 * @param service
 *           see {@link SaveLocation}.
 * @param username
 *           the username/email associated with the cloud service being saved to. Use null if a mapping between
 *           the AAD username and the cloud service username does not exist or the username is not known.
 * @return true if the location can be saved to by the identity, false if otherwise.
 */
boolean getIsSaveToLocationAllowed(SaveLocation service, String username);

/**
 * Whether the SDK PIN prompt is enabled for the app.
 *
 * @return True if the PIN is enabled. False otherwise.
 */
boolean getIsPinRequired();

/**
 * Whether the Intune Managed Browser is required to open web links.
 * @return True if the Managed Browser is required, false otherwise
 */
boolean getIsManagedBrowserRequired();

/**
 * Check if policy allows Contact sync to local contact list.
 *
 * @return True if Contact sync is allowed to save to local contact list; false otherwise.
 */
boolean getIsContactSyncAllowed();

/**
 * Return the policy in string format to the app.
 *  
 * @return The string representing the policy.
 */
String toString();

}
Nota

MAMPolicyManager.getPolicy restituisce sempre criteri per le app diversi da Null, anche se l'app o il dispositivo non è controllato da criteri di gestione di Intune.MAMPolicyManager.getPolicy will always return a non-null App Policy, even if the device or app is not under an Intune management policy.

Esempio: determinare se è necessario il PIN per l'appExample: Determine if PIN is required for the app

Se l'app prevede un'esperienza utente specifica per l'uso del PIN, è consigliabile disabilitarla se l'amministratore IT ha configurato l'SDK in modo da chiedere il PIN per l'app.If the app has its own PIN user experience, you might want to disable it if the IT administrator has configured the SDK to prompt for an app PIN. Per determinare se l'amministratore IT ha distribuito i criteri relativi al PIN per l'app per l'utente finale corrente, chiamare il metodo seguente:To determine if the IT administrator has deployed the app PIN policy to this app, for the current end user, call the following method:

MAMComponents.get(AppPolicy.class).getIsPinRequired();

Esempio: determinare l'utente primario di IntuneExample: Determine the primary Intune user

Oltre che dalle API esposte in AppPolicy, il nome dell'entità utente (UPN) è esposto anche dall'API getPrimaryUser() definita nell'interfaccia MAMUserInfo.In addition to the APIs exposed in AppPolicy, the user principal name (UPN) is also exposed by the getPrimaryUser() API defined inside the MAMUserInfo interface. Per ottenere il nome dell'entità utente, eseguire questa chiamata:To get the UPN, call the following:

MAMUserInfo info = MAMComponents.get(MAMUserInfo.class);
if (info != null) return info.getPrimaryUser();

Di seguito è riportata la definizione completa dell'interfaccia MAMUserInfo:The full definition of the MAMUserInfo interface is below:

/**
 * External facing user informations.
 *
 */
public interface MAMUserInfo {
       /**
        * Get the primary user name.
        *
        * @return the primary user name or null if the device is not enrolled.
        */
       String getPrimaryUser();
}

Esempio: determinare se il salvataggio nel dispositivo o in un servizio di archiviazione cloud è consentitoExample: Determine if saving to device or cloud storage is permitted

Molte app implementano funzionalità che consentono all'utente finale di salvare file in locale o in un altro servizio di archiviazione cloud.Many apps implement features that allow the end user to save files locally or to a cloud storage service. Intune App SDK permette agli amministratori IT di prevenire la perdita dei dati applicando restrizioni di criteri nel modo che ritengono appropriato all'interno dell'organizzazione.The Intune App SDK allows IT administrators to protect against data leakage by applying policy restrictions as they see fit in their organization. Uno dei criteri che gli amministratori IT possono controllare determina se l'utente finale possa o meno eseguire salvataggi in un archivio dati non gestito "personale".One of the policies that IT can control is whether the end user can save to a "personal," unmanaged data store. È incluso il salvataggio in un percorso locale, una scheda SD o un servizio di backup di terze parti.This includes saving to a local location, SD card, or third-party backup services.

La partecipazione dell'app è necessaria per l'abilitazione della funzionalità.App participation is needed to enable the feature. Se l'app consente il salvataggio in percorsi personali o nel cloud direttamente dall'app stessa, è necessario implementare questa funzionalità per garantire che l'amministratore IT possa controllare se il salvataggio in una determinata posizione è consentito o meno.If your app allows saving to personal or cloud locations directly from the app, you must implement this feature to ensure that the IT administrator can control whether saving to a location is allowed. L'API seguente consente all'app di stabilire se il salvataggio in un archivio personale è consentito o meno dai criteri correnti dell'amministratore di Intune.The API below lets the app know whether saving to a personal store is allowed by the current Intune administrator's policy. L'app può quindi applicare i criteri, in quanto è in grado di determinare che è disponibile un archivio dati personale per l'utente finale attraverso se stessa.The app can then enforce the policy, since it is aware of personal data store available to the end user through the app.

Per determinare se i criteri vengono applicati, eseguire questa chiamata:To determine if the policy is enforced, make the following call:

MAMComponents.get(AppPolicy.class).getIsSaveToLocationAllowed(
SaveLocation service, String username);

... dove service corrisponde a uno degli elementi SaveLocation seguenti:... where service is one of the following SaveLocations:

* <span data-ttu-id="29a96-280">SaveLocation.ONEDRIVE_FOR_BUSINESS</span><span class="sxs-lookup"><span data-stu-id="29a96-280">SaveLocation.ONEDRIVE_FOR_BUSINESS</span></span>
* <span data-ttu-id="29a96-281">SaveLocation.LOCAL</span><span class="sxs-lookup"><span data-stu-id="29a96-281">SaveLocation.LOCAL</span></span>
* <span data-ttu-id="29a96-282">SaveLocation.SHAREPOINT</span><span class="sxs-lookup"><span data-stu-id="29a96-282">SaveLocation.SHAREPOINT</span></span>

Il metodo precedente per determinare se i criteri di un utente consentivano il salvataggio dei dati in diverse posizioni era la presenza di getIsSaveToPersonalAllowed() all'interno della stessa classe AppPolicy.The previous method of determining whether a user’s policy allowed them to save data to various locations was getIsSaveToPersonalAllowed() within the same AppPolicy class. Questa funzione è ora deprecata e non deve essere usata. La chiamata seguente è equivalente a getIsSaveToPersonalAllowed():This function is now deprecated and should not be used, the following invocation is equivalent to getIsSaveToPersonalAllowed():


MAMPolicyManager.getPolicy(currentActivity).getIsSaveToLocationAllowed(SaveLocation.LOCAL, userNameInQuestion);
Nota

Usare SaveLocation.OTHER se la posizione in questione non è elencata nell'enumerazione SaveLocations.Use SaveLocation.OTHER if the location in question is not listed in the SaveLocations enum.

Eseguire la registrazione per le notifiche dall'SDKRegister for notifications from the SDK

PanoramicaOverview

Intune App SDK consente all'app di controllare il comportamento di determinati criteri, come una cancellazione selettiva, quando vengono distribuiti dall'amministratore IT.The Intune App SDK allows your app to control the behavior of certain policies, such as selective wipe, when they are deployed by the IT administrator. Quando un amministratore IT distribuisce criteri di questo tipo, il servizio Intune invia una notifica all'SDK.When an IT administrator deploys such a policy, the Intune service sends down a notification to the SDK.

L'app deve eseguire la registrazione per le notifiche dall'SDK creando un oggetto MAMNotificationReceiver e registrandolo con MAMNotificationReceiverRegistry.Your app must register for notifications from the SDK by creating a MAMNotificationReceiver and registering it with MAMNotificationReceiverRegistry. Ciò avviene specificando il ricevente e il tipo di notifica desiderato in App.onCreate, come nell'esempio seguente:This is done by providing the receiver and the type of notification desired in App.onCreate, as the example below illustrates:

@Override
public void onCreate() {
    super.onCreate();
    MAMComponents.get(MAMNotificationReceiverRegistry.class)
        .registerReceiver(
            new ToastNotificationReceiver(),
            MAMNotificationType.WIPE_USER_DATA);
    }

MAMNotificationReceiverMAMNotificationReceiver

L'interfaccia MAMNotificationReceiver riceve semplicemente le notifiche dal servizio Intune.The MAMNotificationReceiver interface simply receives notifications from the Intune service. Alcune notifiche vengono gestite direttamente dall'SDK, mentre altre richiedono la partecipazione dell'app.Some notifications are handled by the SDK directly, while others require the app's participation. Un'app deve restituire true o false da una notifica.An app must return either true or false from a notification. L'app deve sempre restituire true, a meno che un'azione che l'app tenta di eseguire come risultato della notifica non riesca.It must always return true unless some action it tried to take as a result of the notification failed.

  • Questo errore può essere segnalato al servizio Intune.This failure may be reported to the Intune service. Uno dei casi in cui la segnalazione è appropriata è quando un'app non riesce a cancellare i dati utente dopo che l'amministratore IT avvia una cancellazione.An example of a scenario to report is if the app fails to wipe user data after the IT administrator initiates a wipe.
Nota

Il blocco in MAMNotificationReceiver.onReceive è sicuro, in quanto il callback non viene eseguito nel thread dell'interfaccia utente.It is safe to block in MAMNotificationReceiver.onReceive because its callback is not running on the UI thread.

L'interfaccia MAMNotificationReceiver come definita nell'SDK è inclusa di seguito:The MAMNotificationReceiver interface as defined in the SDK is included below :

/**
 * The SDK is signaling that a MAM event has occurred.
 *
 */
public interface MAMNotificationReceiver {

    /**
     * A notification was received.
     *
     * @param notification
     *            The notification that was received.
     * @return The receiver should return true if it handled the
     *   notification without error (or if it decided to ignore the
     *   notification). If the receiver tried to take some action in
     *   response to the notification but failed to complete that
     *   action it should return false.
     */
    boolean onReceive(MAMNotification notification);
}

Tipi di notificheTypes of notifications

Le notifiche seguenti vengono inviate all'app e alcune possono richiedere la partecipazione dell'app:The following notifications are sent to the app and some of them may require app participation:

  • WIPE_USER_DATA: questa notifica viene inviata in una classe MAMUserNotification.WIPE_USER_DATA: This notification is sent in a MAMUserNotification class. Alla ricezione della notifica, è previsto che l'app elimini tutti i dati associati all'identità "aziendale" passata con MAMUserNotification.When this notification is received, the app is expected to delete all data associated with the "corporate" identity passed with the MAMUserNotification. Questa notifica viene attualmente inviata durante l'annullamento della registrazione del servizio APP-WE.This notification is currently sent during APP-WE service unenrollment. Il nome primario dell'utente viene in genere specificato durante il processo di registrazione.The user's primary name is typically specified during the enrollment process. Se si effettua la registrazione per questa notifica, l'app deve garantire che tutti i dati utente siano stati eliminati.If you register for this notification, your app must ensure that all the user's data has been deleted. Se la registrazione non viene effettuata, verrà usato il comportamento di cancellazione selettiva predefinito.If you don't register for it, the default selective wipe behavior will be performed.

  • WIPE_USER_AUXILIARY_DATA: le app possono eseguire la registrazione per questa notifica se vogliono che Intune App SDK usi il comportamento predefinito di cancellazione selettiva, ma vogliono comunque poter rimuovere alcuni dati ausiliari quando viene eseguita la cancellazione.WIPE_USER_AUXILIARY_DATA: Apps can register for this notification if they'd like the Intune App SDK to perform the default selective wipe behavior, but would still like to remove some auxiliary data when the wipe occurs.

  • REFRESH_POLICY: questa notifica viene inviata in un oggetto MAMUserNotification.REFRESH_POLICY: This notification is sent in a MAMUserNotification. Alla ricezione di questa notifica, qualsiasi criterio di Intune memorizzato nella cache deve essere invalidato e aggiornato.When this notification is received, any cached Intune policy must be invalidated and updated. Questa operazione viene gestita in genere dall'SDK, ma deve essere gestita dall'app se i criteri vengono usati in un modo permanente.This is generally handled by the SDK; however, it should be handled by the app if the policy is used in any persistent way.

  • MANAGEMENT_REMOVED: questa notifica viene inviata in un oggetto MAMUserNotification e informa l'app che sta per diventare non gestita.MANAGEMENT_REMOVED: This notification is sent in a MAMUserNotification and informs the app that it is about to become unmanaged. Quando non è gestita, l'app non può più leggere i file crittografati, leggere i dati crittografati con MAMDataProtectionManager, interagire con gli Appunti crittografati o partecipare in altro modo all'ecosistema di app gestite.Once unmanaged, it will no longer be able to read encrypted files, read data encrypted with MAMDataProtectionManager, interact with the encrypted clipboard, or otherwise participate in the managed-app ecosystem.

Nota

Un'app non deve mai eseguire la registrazione sia per le notifiche WIPE_USER_DATA che per le notifiche WIPE_USER_AUXILIARY_DATA.An app should never register for both the WIPE_USER_DATA and WIPE_USER_AUXILIARY_DATA notifications.

Configurare Azure Active Directory Authentication Library (ADAL)Configure Azure Active Directory Authentication Library (ADAL)

Leggere prima di tutto le linee guida sull'integrazione di ADAL disponibili nel repository ADAL su GitHub.First, please read the ADAL integration guidelines found in the ADAL repository on GitHub.

L'SDK si basa su ADAL per gli scenari di autenticazione e avvio condizionale, che richiedono la configurazione delle app con Azure Active Directory.The SDK relies on ADAL for its authentication and conditional launch scenarios, which require apps to be configured with Azure Active Directory. I valori di configurazione vengono comunicati all'SDK tramite i metadati di AndroidManifest.The configuration values are communicated to the SDK via AndroidManifest metadata.

Per configurare l'app e abilitare l'autenticazione appropriata, aggiungere il codice seguente al nodo dell'app in AndroidManifest.xml.To configure your app and enable proper authentication, add the following to the app node in AndroidManifest.xml. Alcune di queste configurazioni sono necessarie solo se l'app usa ADAL per l'autenticazione in generale. In questo caso, saranno necessari i valori specifici usati dall'app per registrare se stessa con AAD.Some of these configurations are only required if your app uses ADAL for authentication in general; in that case, you will need the specific values your app uses to register itself with AAD. Questo avviene per evitare che all'utente finale venga chiesta l'autenticazione due volte, a causa del fatto che AAD riconosce due valori di registrazione separati, uno dall'app e uno dall'SDK.This is done to ensure that the end user does not get prompted for authentication twice, due to AAD recognizing two separate registration values: one from the app and one from the SDK.

<meta-data
    android:name="com.microsoft.intune.mam.aad.Authority"
    android:value="https://AAD authority/" />
<meta-data
    android:name="com.microsoft.intune.mam.aad.ClientID"
    android:value="your-client-ID-GUID" />
<meta-data
    android:name="com.microsoft.intune.mam.aad.NonBrokerRedirectURI"
    android:value="your-redirect-URI" />
<meta-data
    android:name="com.microsoft.intune.mam.aad.SkipBroker"
    android:value="[true | false]" />

Metadati ADALADAL metadata

  • Authority è l'autorità AAD corrente in uso.Authority is the current AAD authority in use. Se presente, è necessario usare l'ambiente specifico in cui sono stati configurati gli account AAD.If present, you should use your own environment where AAD accounts have been configured. Se questo valore è assente, viene usato un valore predefinito di Intune.If this value is absent, an Intune default is used.

  • ClientID è l'ID client AAD da usare.ClientID is the AAD ClientID to be used. È necessario usare l'ID client dell'app, se è stata eseguita la registrazione con Azure AD.You should use your own app's ClientID if it is registered with Azure AD. Se questo valore è assente, viene usato un valore predefinito di Intune.If this value is absent, an Intune default is used.

  • NonBrokerRedirectURI è l'URI di reindirizzamento di AAD da usare in assenza del broker.NonBrokerRedirectURI is the AAD redirect URI to use in broker-less cases. Se non è specificato alcun valore, viene usato il valore predefinito urn:ietf:wg:oauth:2.0:oob.If none is specified, a default value of urn:ietf:wg:oauth:2.0:oob is used. Questo valore predefinito è appropriato per la maggior parte delle app.This default is suitable for most apps.

  • SkipBroker viene usato nel caso in cui l'ID client non sia stato configurato per usare l'URI di reindirizzamento del broker.SkipBroker is used in case the ClientID has not been configured to use the broker redirect URI. Il valore predefinito è "false".The default value is "false."

    • Per le app che non integrano ADAL e non richiedono di partecipare all'autenticazione negoziata/SSO a livello di dispositivo, questo valore deve essere impostato su "true".For apps that do not integrate ADAL and do not want to participate in device-wide brokered authentication/SSO, this should be set to "true." Quando questo valore è "true", l'unico URI di reindirizzamento usato è NonBrokerRedirectURI.When this value is "true," the only redirect URI that will be used is NonBrokerRedirectURI.

    • Per le app che non supportano la negoziazione SSO a livello di dispositivo, il valore deve essere "false".For apps that do support device-wide SSO brokering, this should be "false." Quando il valore è "false", l'SDK sceglie un broker tra il risultato di com.microsoft.aad.adal.AuthenticationContext.getRedirectUriForBroker() e NonBrokerRedirectURI, in base alla disponibilità del broker nel sistema.When the value is "false," the SDK will select a broker between the result of com.microsoft.aad.adal.AuthenticationContext.getRedirectUriForBroker() and NonBrokerRedirectURI, based on the availability of the broker on the system. In generale, il broker è disponibile nell'app Portale aziendale o nell'app Azure Authenticator.In general, the broker will be available from the Company Portal app or Azure Authenticator app.

Configurazioni comuni di ADALCommon ADAL configurations

Di seguito sono indicati alcuni modi comuni di configurazione di un'app con ADAL.The following are common ways an app can be configured with ADAL. Trovare la configurazione dell'app e assicurarsi di impostare i parametri dei metadati ADAL (illustrati in precedenza) sui valori necessari.Find your app's configuration and make sure to set the ADAL metadata parameters (explained above) to the necessary values.

  1. App che non integra ADAL:App does not integrate ADAL:

    Parametro ADAL obbligatorioRequired ADAL parameter ValoreValue
    AuthorityAuthority Ambiente desiderato in cui sono stati configurati gli account AADDesired environment where AAD accounts have been configured
    SkipBrokerSkipBroker TrueTrue
  2. App che integra ADAL:App integrates ADAL:

    Parametro ADAL obbligatorioRequired ADAL parameter ValoreValue
    AuthorityAuthority Ambiente desiderato in cui sono stati configurati gli account AADDesired environment where AAD accounts have been configured
    ClientIDClientID ID client dell'app (generato da Azure AD al momento della registrazione dell'app)The app's ClientID (generated by Azure AD when the app is registered)
    NonBrokerRedirectURINonBrokerRedirectURI URI di reindirizzamento valido per l'app o urn:ietf:wg:oauth:2.0:oob per impostazione predefinita.A valid redirect URI for the app, or urn:ietf:wg:oauth:2.0:oob by default.

    Assicurarsi di configurare il valore come URI di reindirizzamento accettabile per l'ID client dell'app.Make sure to configure the value as an acceptable redirect URI for your app's ClientID.
    SkipBrokerSkipBroker FalseFalse
  3. App che integra ADAL ma non supporta l'autenticazione negoziata/SSO a livello di dispositivo:App integrates ADAL but does not support brokered authentication/device-wide SSO:

    Parametro ADAL obbligatorioRequired ADAL parameter ValoreValue
    AuthorityAuthority Ambiente desiderato in cui sono stati configurati gli account AADDesired environment where AAD accounts have been configured
    ClientIDClientID ID client dell'app (generato da Azure AD al momento della registrazione dell'app)The app's ClientID (generated by Azure AD when the app is registered)
    NonBrokerRedirectURINonBrokerRedirectURI URI di reindirizzamento valido per l'app o urn:ietf:wg:oauth:2.0:oob per impostazione predefinita.A valid redirect URI for the app, or urn:ietf:wg:oauth:2.0:oob by default.

    Assicurarsi di configurare il valore come URI di reindirizzamento accettabile per l'ID client dell'app.Make sure to configure the value as an acceptable redirect URI for your app's ClientID.
    SkipBrokerSkipBroker TrueTrue

Criteri di protezione delle app senza registrazione del dispositivoApp protection policy without device enrollment

PanoramicaOverview

I criteri di protezione delle app di Intune senza registrazione del dispositivo, noti anche come APP-WE o MAM-WE, consentono la gestione delle app da Intune senza richiedere la registrazione del dispositivo nella soluzione MDM di Intune.Intune app protection policy without device enrollment, also known as APP-WE or MAM-WE, allows apps to be managed by Intune without the need for the device to be enrolled Intune MDM. APP-WE funziona con o senza registrazione del dispositivo.APP-WE works with or without device enrollment. Il Portale aziendale deve comunque essere installato nel dispositivo, ma l'utente non deve necessariamente accedervi e registrare il dispositivo.The Company Portal is still required to be installed on the device, but the user does not need to sign into the Company Portal and enroll the device.

Nota

Tutte le app devono supportare i criteri di protezione delle app senza registrazione del dispositivo.All apps are required to support app protection policy without device enrollment.

Flusso di lavoroWorkflow

Quando un'app crea un nuovo account utente, deve registrare l'account per la gestione con Intune App SDK.When an app creates a new user account, it should register the account for management with the Intune App SDK. L'SDK gestisce i dettagli della registrazione dell'app nel servizio APP-WE. Se necessario, in caso di errore, esegue nuovi tentativi di registrazione a intervalli di tempo appropriati.The SDK will handle the details of enrolling the app in the APP-WE service; if necessary, it will retry any enrollments at appropriate time intervals if failures occur.

L'app può anche eseguire una query su Intune App SDK in relazione allo stato di un utente registrato per determinare se all'utente deve essere impedito l'accesso al contenuto aziendale.The app can also query the Intune App SDK for the status of a registered user to determine if the user should be blocked from accessing corporate content. È possibile registrare più account per la gestione, ma attualmente è possibile registrare attivamente con il servizio APP-WE un solo account per volta.Multiple accounts may be registered for management, but currently only one account can be actively enrolled with the APP-WE service at a time. Ciò significa che nell'app un solo account per volta può ricevere i criteri di protezione delle app.This means only one account on the app can receive app protection policy at a time.

L'app deve fornire un callback per acquisire il token di accesso appropriato da Azure Active Directory Authentication Library (ADAL) per conto dell'SDK.The app is required to provide a callback to acquire the appropriate access token from the Azure Active Directory Authentication Library (ADAL) on behalf of the SDK. Si presuppone che l'app usi già ADAL per l'autenticazione utente e per acquisire i propri token di accesso.It is assumed that the app already uses ADAL for user authentication and to acquire its own access tokens.

Quando l'app rimuove completamente un account, deve annullare la registrazione dell'account per indicare che l'app non deve più applicare i criteri per tale utente.When the app removes an account completely, it should unregister that account to indicate that the app should no longer apply policy for that user. Se l'utente è stato registrato nel servizio MAM, la sua registrazione sarà annullata e l'app verrà cancellata.If the user was enrolled in the MAM service, the user will be unenrolled and the app will be wiped.

Panoramica dei requisiti dell'appOverview of app requirements

Per implementare l'integrazione APP-WE, l'app deve registrare l'account utente con MAM SDK:To implement APP-WE integration, your app must register the user account with the MAM SDK:

  1. L'app deve implementare e registrare un'istanza dell'interfaccia MAMServiceAuthenticationCallback.The app must implement and register an instance of the MAMServiceAuthenticationCallback interface. L'istanza di callback deve essere registrata il prima possibile nel ciclo di vita dell'app (in genere nel metodo onMAMCreate() della classe dell'applicazione).The callback instance should be registered as early as possible in the app's lifecycle (typically in the onMAMCreate() method of the application class).

  2. Quando viene creato un account utente e l'utente accede correttamente con ADAL, l'app deve chiamare registerAccountForMAM().When a user account is created and the user successfully signs in with ADAL, the app must call the registerAccountForMAM().

  3. Quando un account utente viene completamente rimosso, l'app deve chiamare unregisterAccountForMAM() per rimuovere l'account dalla gestione di Intune.When a user account is completely removed, the app should call unregisterAccountForMAM() to remove the account from Intune management.

    Nota

    Se un utente si disconnette temporaneamente dall'app, non è necessario che l'app chiami unregisterAccountForMAM().If a user signs out of the app temporarily, the app does not need to call unregisterAccountForMAM(). La chiamata può avviare una cancellazione per rimuovere completamente i dati aziendali per l'utente.The call may initiate a wipe to completely remove corporate data for the user.

MAMEnrollmentManagerMAMEnrollmentManager

Tutte le API di autenticazione e registrazione necessarie sono disponibili nell'interfaccia MAMEnrollmentManager.All the necessary authentication and registration APIs can be found in the MAMEnrollmentManager interface. È possibile ottenere un riferimento a MAMEnrollmentManager come indicato di seguito:A reference to the MAMEnrollmentManager can be obtained as follows:

MAMEnrollmentManager mgr = MAMComponents.get(MAMEnrollmentManager.class);

// make use of mgr

L'istanza di MAMEnrollmentManager restituita non è sicuramente Null.The MAMEnrollmentManager instance returned is guaranteed not to be null. I metodi API rientrano in due categorie: autenticazione e registrazione dell'account.The API methods fall into two categories: authentication and account registration.

Nota

MAMEnrollmentManager include alcuni metodi API che saranno presto deprecati.MAMEnrollmentManager contains some API methods that will be deprecated soon. Per maggiore chiarezza, nel blocco di codice riportato di seguito vengono visualizzati solo i metodi e i codici di risultato rilevanti.For clarity, only the relevant methods and result codes are shown in the code block below.

package com.microsoft.intune.mam.policy;

public interface MAMEnrollmentManager {
    public enum Result {
        AUTHORIZATION_NEEDED,
        NOT_LICENSED,
        ENROLLMENT_SUCCEEDED,
        ENROLLMENT_FAILED,
        WRONG_USER,
        MDM_ENROLLED,
        UNENROLLMENT_SUCCEEDED,
        UNENROLLMENT_FAILED,
        PENDING,
        COMPANY_PORTAL_REQUIRED;
    }

    //Authentication methods
    interface MAMServiceAuthenticationCallback {
        String acquireToken(String upn, String aadId, String resourceId);
    }
    void registerAuthenticationCallback(MAMServiceAuthenticationCallback callback);
    void updateToken(String upn, String aadId, String resourceId, String token);

    //Registration methods
    void registerAccountForMAM(String upn, String aadId, String tenantId);
    void unregisterAccountForMAM(String upn);
    Result getRegisteredAccountStatus(String upn);
}

Autenticazione di accountAccount authentication

Questa sezione descrive i metodi API di autenticazione in MAMEnrollmentManager e come usarli.This section describes the authentication API methods in MAMEnrollmentManager and how to use them.

interface MAMServiceAuthenticationCallback {
        String acquireToken(String upn, String aadId, String resourceId);
}
void registerAuthenticationCallback(MAMServiceAuthenticationCallback callback);
void updateToken(String upn, String aadId, String resourceId, String token);
  1. L'app deve implementare l'interfaccia MAMServiceAuthenticationCallback per consentire all'SDK di richiedere un token ADAL per l'utente e l'ID risorsa specifici.The app must implement the MAMServiceAuthenticationCallback interface to allow the SDK to request an ADAL token for the given user and resource ID. L'istanza di callback deve essere fornita a MAMEnrollmentManager chiamando il relativo metodo registerAuthenticationCallback().The callback instance must be provided to the MAMEnrollmentManager by calling its registerAuthenticationCallback() method. Potrebbe essere necessario un token molto presto nel ciclo di vita dell'app per i nuovi tentativi di registrazione o le archiviazioni di aggiornamento dei criteri di protezione delle app, quindi la posizione ideale per registrare il callback è all'interno del metodo onMAMCreate() della sottoclasse MAMApplication dell'app.A token may be needed very early in the app lifecycle for enrollment retries or app protection policy refresh check-ins, so the ideal place to register the callback is in the onMAMCreate() method of the app's MAMApplication subclass.

  2. Il metodo acquireToken() deve acquisire il token di accesso per l'ID risorsa richiesto per l'utente specificato.The acquireToken() method should acquire the access token for the requested resource ID for the given user. Se non è possibile acquisire il token richiesto, il metodo deve restituire Null.If it can't acquire the requested token, it should return null.

  3. Nel caso in cui l'app non sia in grado di fornire un token quando l'SDK chiama acquireToken(), ad esempio, se si verifica un errore nel processo di autenticazione invisibile all'utente e non è il momento adatto per visualizzare un'interfaccia utente, l'app può fornire un token in un secondo momento chiamando il metodo updateToken().In case the app is unable to provide a token when the SDK calls acquireToken() -- for example, if silent authentication fails and it is an inconvenient time to show a UI -- the app can provide a token at a later time by calling the updateToken() method. Gli stessi valori di UPN, ID di AAD e ID risorsa richiesti dalla chiamata precedente di acquireToken() devono essere passati a updateToken(), insieme al token acquisito.The same UPN, AAD ID, and resource ID that were requested by the prior call to acquireToken() must be passed to updateToken(), along with the token that was finally acquired. L'app deve chiamare questo metodo non appena possibile dopo la restituzione di Null dal callback fornito.The app should call this method as soon as possible after returning null from the provided callback.

Nota

L'SDK chiamerà acquireToken() periodicamente per ottenere il token, quindi la chiamata di updateToken() non è strettamente necessaria.The SDK will call acquireToken() periodically to get the token, so calling updateToken() is not strictly required. È tuttavia consigliabile, perché può essere utile per consentire di completare in modo tempestivo le registrazioni e le archiviazioni dei criteri di protezione delle app.However, it is recommended as it can help enrollments and app protection policy check-ins complete in a timely manner.

Registrazione di accountAccount registration

Questa sezione descrive i metodi API di registrazione degli account in MAMEnrollmentManager e come usarli.This section describes the account registration API methods in MAMEnrollmentManager and how to use them.

void registerAccountForMAM(String upn, String aadId, String tenantId);
void unregisterAccountForMAM(String upn);
Result getRegisteredAccountStatus(String upn);
  1. Per registrare un account per la gestione, l'app deve chiamare registerAccountForMAM().To register an account for management, the app should call registerAccountForMAM(). Un account utente è identificato dal relativo UPN e dall'ID utente AAD.A user account is identified by both its UPN and its AAD user ID. L'ID tenant è anch'esso necessario per associare i dati di registrazione al tenant AAD dell'utente.The tenant ID is also required to associate enrollment data with the user's AAD tenant. L'SDK può cercare di registrare l'app per l'utente specifico nel servizio MAM. Se la registrazione non riesce, viene eseguito periodicamente un nuovo tentativo fino a quando la registrazione dell'account non viene annullata.The SDK may attempt to enroll the app for the given user in the MAM service; if enrollment fails, it will periodically retry enrollment until the account is unregistered. L'intervallo tra tentativi è in genere di 12-24 ore.The retry period will typically be 12-24 hours. L'SDK fornisce lo stato dei tentativi di registrazione in modo asincrono tramite notifiche.The SDK provides the status of enrollment attempts asynchronously via notifications.

  2. Poiché l'autenticazione di AAD è necessaria, il momento migliore per registrare l'account utente è dopo che l'utente ha eseguito l'accesso nell'app e viene autenticato correttamente usando ADAL.Because AAD authentication is required, the best time to register the user account is after the user has signed into the app and is successfully authenticated using ADAL.

    • L'ID AAD e l'ID tenant dell'utente vengono restituiti dalla chiamata di autenticazione ADAL come parte dell'oggetto AuthenticationResult.The user's AAD ID and tenant ID are returned from the ADAL authentication call as part of the AuthenticationResult object. L'ID tenant proviene dal metodo AuthenticationResult.getTenantID().The tenant ID comes from the AuthenticationResult.getTenantID() method.
    • Le informazioni sull'utente sono disponibili in un oggetto secondario di tipo UserInfo proveniente da AuthenticationResult.getUserInfo() e l'ID utente AAD viene recuperato da tale oggetto chiamando UserInfo.getUserId().Information about the user is found in a sub-object of type UserInfo that comes from AuthenticationResult.getUserInfo(), and the AAD user ID is retrieved from that object by calling UserInfo.getUserId().
  3. Per annullare la registrazione di un account dalla gestione di Intune, l'app deve chiamare unregisterAccountForMAM().To unregister an account from Intune management, the app should call unregisterAccountForMAM(). Se l'account è stato registrato correttamente e viene gestito, l'SDK annullerà la registrazione dell'account e ne cancellerà i dati.If the account has been successfully enrolled and is managed, the SDK will unenroll the account and wipe its data. I tentativi periodici di registrazione per l'account verranno arrestati.Periodic enrollment retries for the account will be stopped. L'SDK fornisce lo stato della richiesta di annullamento della registrazione in modo asincrono tramite notifiche.The SDK provides the status of unenrollment request asynchronously via notifications.

Note di implementazione importantiImportant implementation notes

AutenticazioneAuthentication

  • Quando l'app chiama registerAccountForMAM(), può ricevere un callback nell'interfaccia MAMServiceAuthenticationCallback poco dopo, in un thread diverso.When the app calls registerAccountForMAM(), it may receive a callback on its MAMServiceAuthenticationCallback interface shortly thereafter, on a different thread. Idealmente, l'app ha acquisito il proprio token da ADAL prima della registrazione dell'account per accelerare l'acquisizione del token di MAMService.Ideally, the app acquired its own token from ADAL prior to registering the account to expedite the acquisition of the MAMService token. Se l'app restituisce un token valido dal callback, la registrazione continua e l'app ottiene il risultato finale tramite una notifica.IF the app returns a valid token from the callback, enrollment will proceed and the app will get the final result via a notification.

  • Se l'app non restituisce un token AAD valido, il risultato finale del tentativo di registrazione è AUTHENTICATION_NEEDED.If the app doesn't return a valid AAD token, the final result from the enrollment attempt will be AUTHENTICATION_NEEDED. Se l'app riceve il risultato tramite notifica, può accelerare il processo di registrazione acquisendo il token di MAMService e chiamando il metodo updateToken() per avviare di nuovo il processo di registrazione.If the app receives this Result via notification, it can expedite the enrollment process by acquiring the MAMService token and calling the updateToken() method to initiate the enrollment process again. Questo tuttavia non è un requisito fisso, perché l'SDK esegue periodicamente nuovi tentativi di registrazione e richiama il callback per acquisire il token.This is not a firm requirement, however, since the SDK retries enrollment periodically and invokes the callback to acquire the token.

  • L'oggetto MAMServiceAuthenticationCallback registrato dell'app verrà chiamato anche per acquisire un token per le archiviazioni di aggiornamento dei criteri di protezione delle app periodiche.The app's registered MAMServiceAuthenticationCallback will also be called to acquire a token for periodic app protection policy refresh check-ins. Se l'app non è in grado di fornire un token quando richiesto, non riceve una notifica, ma deve tentare di acquisire un token e chiamare updateToken() al successivo momento opportuno per accelerare il processo di archiviazione.If the app is unable to provide a token when requested, it will not get a notification, but it should attempt to acquire a token and call updateToken() at the next convenient time to expedite the check-in process. Se non viene fornito un token, il callback verrà comunque chiamato al successivo tentativo di archiviazione.If a token is not provided, the callback will still be called at the next check-in attempt.

RegistrazioneRegistration

  • Per praticità, i metodi di registrazione sono idempotenti. Ad esempio, registerAccountForMAM() registra un account ed esegue un tentativo di registrazione dell'app solo se l'account non è già registrato e unregisterAccountForMAM() annulla la registrazione di un account solo se è attualmente registrato.For your convenience, the registration methods are idempotent; for example, registerAccountForMAM()will only register an account and attempt to enroll the app if the account is not already registered, and unregisterAccountForMAM() will only unregister an account if it is currently registered. Le chiamate successive non hanno effetto, quindi se i metodi vengono chiamati più di una volta non ci sono problemi.Subsequent calls are no-ops, so there is no harm in calling these methods more than once. Inoltre, non è garantita la corrispondenza tra le chiamate a questi metodi e le notifiche dei risultati: ad esempio, se viene chiamato il metodo registerAccountForMAM per un'identità già registrata, potrebbe non venire inviata di nuovo la notifica per tale identità.Additionally, correspondence between calls to these methods and notifications of results are not guaranteed: i.e. if registerAccountForMAM is called for an identity that is already registered, the notification may not be sent again for that identity. È possibile che vengano inviate notifiche che non corrispondono alle chiamate a questi metodi, perché l'SDK può eseguire periodicamente tentativi di registrazione in background e possono essere avviate operazioni di annullamento della registrazione da richieste di cancellazione ricevute dal servizio Intune.It is possible that notifications are sent that don't correspond to any calls to these methods, since the SDK may periodically try enrollments in the background, and unenrollments may be triggered by wipe requests received from the Intune service.

  • I metodi di registrazione possono essere chiamati per un numero qualsiasi di identità diverse, ma attualmente può venire registrato correttamente un solo account utente.The registration methods can be called for any number of different identities, but currently only one user account can become successfully enrolled. Se più account utente con licenza per Intune e interessati dai criteri di protezione delle app vengono registrati contemporaneamente o quasi, non è garantito quale account verrà registrato correttamente.If multiple user accounts that are licensed for Intune and targeted by app protection policy are registered at or near the same time, there is no guarantee on which one will win the race.

  • Infine, è possibile eseguire una query su MAMEnrollmentManager per verificare se un account specifico è stato registrato e ottenere il suo stato corrente usando il metodo getRegisteredAccountStatus.Finally, you can query the MAMEnrollmentManager to see if a particular account is registered and to get its current status using the getRegisteredAccountStatus method. Se l'account fornito non è registrato, questo metodo restituisce Null.If the provided account is not registered, this method will return null. Se l'account è registrato, questo metodo restituisce lo stato dell'account come uno dei membri dell'enumerazione MAMEnrollmentManager.Result.If the account is registered, this method will return the account's status as one of the members of the MAMEnrollmentManager.Result enumeration.

Codici di risultato e statoResult and status codes

Quando un account viene registrato per la prima volta, ha uno stato iniziale PENDING, che indica che il tentativo di registrazione del servizio MAM iniziale è incompleto.When an account is first registered, it begins in the PENDING state, indicating that the initial MAM service enrollment attempt is incomplete. Al termine del tentativo di registrazione, viene inviata una notifica con uno dei codici di risultato indicati nella tabella seguente.After the enrollment attempt finishes, a notification will be sent with one of the Result codes in the table below. Il metodo getRegisteredAccountStatus() restituisce inoltre lo stato dell'account, in modo che l'app possa sempre determinare se l'accesso al contenuto aziendale è bloccato per l'utente.In addition, the getRegisteredAccountStatus() method will return the account's status so the app can always determine if access to corporate content is blocked for that user. Se il tentativo di registrazione non riesce, lo stato dell'account può cambiare nel tempo in quanto l'SDK esegue nuovi tentativi di registrazione in background.If the enrollment attempt fails, the account's status may change over time as the SDK retries enrollment in the background.

Codice di risultatoResult code SpiegazioneExplanation
AUTHORIZATION_NEEDEDAUTHORIZATION_NEEDED Questo risultato indica che non è stato fornito un token dall'istanza di MAMServiceAuthenticationCallback registrata dell'app o che il token fornito non è valido.This result indicates that a token was not provided by the app’s registered MAMServiceAuthenticationCallback instance, or the provided token was invalid. L'app deve acquisire un token valido e chiamare updateToken(), se possibile.The app should acquire a valid token and call updateToken() if possible.
NOT_LICENSEDNOT_LICENSED L'utente non ha una licenza per Intune oppure il tentativo di contattare il servizio MAM di Intune non è riuscito.The user is not licensed for Intune, or the attempt to contact the Intune MAM service failed. L'app deve continuare in uno stato non gestito (normale) e l'utente non deve essere bloccato.The app should continue in an unmanaged (normal) state and the user should not be blocked. Verranno eseguiti periodicamente nuovi tentativi di registrazione, nel caso in cui in futuro l'utente disponga di una licenza.Enrollments will be retried periodically in case the user becomes licensed in the future.
ENROLLMENT_SUCCEEDEDENROLLMENT_SUCCEEDED Il tentativo di registrazione ha avuto esito positivo oppure l'utente è già registrato.The enrollment attempt succeeded, or the user is already enrolled. Nel caso di una registrazione con esito positivo, verrà inviata una notifica di aggiornamento dei criteri prima di questa notifica.In the case of a successful enrollment, a policy refresh notification will be sent before this notification. L'accesso ai dati aziendali deve essere consentito.Access to corporate data should be allowed.
ENROLLMENT_FAILEDENROLLMENT_FAILED Il tentativo di registrazione non è riuscito.The enrollment attempt failed. Maggiori dettagli sono disponibili nei log del dispositivo.Further details can be found in the device logs. L'app non deve consentire l'accesso alle risorse aziendali in questo stato, perché è stato stabilito in precedenza che l'utente ha una licenza per Intune.The app should not allow access to corporate in this state, since it was previously determined that the user is licensed for Intune.
WRONG_USERWRONG_USER Un solo utente per dispositivo può registrare un'app con il servizio MAM.Only one user per device can enroll an app with the MAM service. Per eseguire correttamente la registrazione come utente diverso, è prima necessario annullare la registrazione di tutte le app registrate.In order to enroll successfully as a different user, all enrolled apps must be unenrolled first. In caso contrario, l'app deve eseguire la registrazione come utente primario.Otherwise, this app must enroll as the primary user. Questo controllo viene eseguito dopo il controllo della licenza, quindi all'utente deve essere impedito l'accesso ai dati aziendali fino a quando la registrazione dell'app non avviene correttamente.This check happens after the license check, so the user should be blocked from accessing corporate data until the app is successfully enrolled.
UNENROLLMENT_SUCCEEDEDUNENROLLMENT_SUCCEEDED L'annullamento della registrazione è avvenuto correttamente.Unenrollment was successful.
UNENROLLMENT_FAILEDUNENROLLMENT_FAILED La richiesta di annullamento della registrazione non è riuscita.The unenrollment request failed. Maggiori dettagli sono disponibili nei log del dispositivo.Further details can be found in the device logs.
PENDINGPENDING Il tentativo di registrazione iniziale per l'utente è in corso.The initial enrollment attempt for the user is in progress. L'app può bloccare l'accesso ai dati aziendali fino a quando non è noto il risultato della registrazione, ma ciò non è necessario.The app can block access to corporate data until the enrollment result is known, but is not required to do so.
COMPANY_PORTAL_REQUIREDCOMPANY_PORTAL_REQUIRED L'utente ha la licenza per Intune, ma l'app non può essere registrata fino a quando non viene installata l'app Portale aziendale nel dispositivo.The user is licensed for Intune, but the app cannot be enrolled until the Company Portal app is installed on the device. Intune App SDK tenta di bloccare l'accesso all'app per l'utente specificato, chiedendo di installare l'app Portale aziendale (vedere di seguito per informazioni dettagliate).The Intune App SDK will attempt to block access to the app for the given user and direct them to install the Company Portal app (see below for details).

Override della richiesta di installazione del Portale aziendale (facoltativo)Company Portal requirement prompt override (optional)

Se viene ricevuto il risultato COMPANY_PORTAL_REQUIRED, l'SDK blocca le attività che usano l'identità per cui è stata richiesta la registrazione.If the COMPANY_PORTAL_REQUIRED Result is received, the SDK will block use of activities that use the identity for which enrollment was requested. L'SDK farà in modo che tali attività visualizzino una richiesta di download del Portale aziendale.Instead, the SDK will cause those activities to display a prompt to download the Company Portal. Se si vuole impedire questo comportamento nell'app, le attività possono implementare MAMActivity.onMAMCompanyPortalRequired.If you want to prevent this behavior in your app, activities may implement MAMActivity.onMAMCompanyPortalRequired.

Questo metodo viene chiamato prima che l'SDK visualizzi l'interfaccia utente di blocco predefinita.This method is called before the SDK displays its default blocking UI. Se l'app modifica l'identità dell'attività o annulla la registrazione dell'utente che ha tentato di eseguire la registrazione, l'SDK non bloccherà l'attività.If the app changes the activity identity or unregisters the user who attempted to enroll, the SDK will not block the activity. In questo caso, è compito dell'app evitare la perdita di dati aziendali.In this situation, it is up to the app to avoid leaking corporate data.

NotificheNotifications

È stato aggiunto un nuovo tipo di oggetto MAMNotification per informare l'app che la richiesta di registrazione è stata completata.A new type of MAMNotification has been added in order to inform the app that the enrollment request has completed. L'oggetto MAMEnrollmentNotification verrà ricevuto tramite l'interfaccia MAMNotificationReceiver, come descritto nella sezione Eseguire la registrazione per le notifiche dall'SDK.The MAMEnrollmentNotification will be received through the MAMNotificationReceiver interface as described in the Register for notifications from the SDK section.

public interface MAMEnrollmentNotification extends MAMUserNotification {
    MAMEnrollmentManager.Result getEnrollmentResult();
}

Il metodo getEnrollmentResult() restituisce il risultato della richiesta di registrazione.The getEnrollmentResult() method returns the result of the enrollment request. Poiché MAMEnrollmentNotification estende MAMUserNotification, è disponibile anche l'identità dell'utente per cui è stato eseguito il tentativo di registrazione.Since MAMEnrollmentNotification extends MAMUserNotification, the identity of the user for whom the enrollment was attempted is also available. L'app deve implementare l'interfaccia MAMNotificationReceiver per ricevere queste notifiche, come descritto nella sezione Eseguire la registrazione per le notifiche dall'SDK.The app must implement the MAMNotificationReceiver interface to receive these notifications, detailed in the Register for notifications from the SDK section.

Lo stato dell'account utente registrato può cambiare quando viene ricevuta una notifica di registrazione, ma in alcuni casi non cambia (ad esempio, se la notifica AUTHORIZATION_NEEDED viene ricevuta dopo un risultato più informativo, come WRONG_USER, come stato dell'account viene mantenuto il risultato più informativo).The registered user account's status may change when an enrollment notification is received, but it will not change in some cases (e.g. if AUTHORIZATION_NEEDED notification is received after a more informative result such as WRONG_USER, the more informative result will be maintained as the account's status)

Protezione dei dati di backupProtecting Backup data

A partire da Android Marshmallow (API 23), Android offre due modi in cui un'app può eseguire il backup dei dati.As of Android Marshmallow (API 23), Android has two ways for an app to back up its data. Ogni opzione è disponibile e richiede procedure diverse per garantire l'implementazione corretta della protezione dati di Intune.Each option is available to your app and requires different steps to ensure that Intune data protection is correctly implemented. È possibile consultare la tabella di seguito per informazioni sulle azioni corrispondenti necessarie per il corretto comportamento di protezione dati.You can review the table below on corresponding actions required for correct data protection behavior. Per altre informazioni sui metodi di backup, vedere la guida alle API di Android.You can read more about the backup methods in the Android API guide.

Backup automatico per le appAuto Backup for Apps

Android ha iniziato a offrire backup completi automatici in Google Drive per le app nei dispositivi Android Marshmallow, indipendentemente dall'API di destinazione dell'app.Android began offering automatic full backups to Google Drive for apps on Android Marshmallow devices, regardless of the app's target API. Nel file AndroidManifest.x ls, se si imposta in modo esplicito android:allowBackup su false, l'app non verrà mai accodata per i backup da Android e i dati "aziendali" rimarranno all'interno dell'app.In your AndroidManifest.xml, if you explicitly set android:allowBackup to false, then your app will never be queued for backups by Android and "corporate" data will stay within the app. In questo caso non è necessaria alcuna azione ulteriore.In this case, no further action is necessary.

Tuttavia, per impostazione predefinita l'attributo android:allowBackup viene impostato su true, anche se android:allowBackup non è specificato nel file manifesto.However, by default the android:allowBackup attribute is set to true, even if android:allowBackup isn't specified in the manifest file. Questo significa che viene eseguito automaticamente il backup di tutti i dati dell'app nell'account Google Drive dell'utente, un comportamento predefinito che comporta il rischio di perdite di dati.This means all app data is automatically backed up to the user's Google Drive account, a default behavior that poses a data leak risk. Per questo motivo l'SDK richiede l'applicazione delle modifiche indicate di seguito per garantire una corretta protezione dei dati.Therefore, the SDK requires the changes outlined below to ensure that data protection is applied. È importante seguire le linee guida seguenti per proteggere i dati dei clienti in modo appropriato, se si vuole eseguire l'app in dispositivi Android Marshmallow.It is important to follow the guidelines below to protect customer data properly if you want your app to run on Android Marshmallow devices.

Intune consente di usare tutte le funzionalità di backup automatico disponibili da Android, inclusa la possibilità di definire regole personalizzate in XML, ma è necessario attenersi alla procedura seguente per proteggere i dati:Intune allows you to utilize all the Auto Backup features available from Android, including the ability to define custom rules in XML, but you must follow the steps below to secure your data:

  1. Se l'app non usa il proprio oggetto BackupAgent personalizzato, usare l'oggetto MAMBackupAgent predefinito per consentire backup completi automatici conformi ai criteri di Intune.If your app does not use its own custom BackupAgent, use the default MAMBackupAgent to allow for automatic full backups that are Intune policy compliant. In questo caso, è possibile ignorare l'attributo del manifesto android:fullBackupOnly, in quanto non è applicabile per l'agente di backup.If you do this, you can ignore the android:fullBackupOnly manifest attribute, as it’s not applicable for our backup agent. Inserire quanto segue nel manifesto dell'app:Place the following in the app manifest:

    android:backupAgent="com.microsoft.intune.mam.client.app.backup.MAMDefaultBackupAgent"
    
  2. [Facoltativo] Se è stato implementato un oggetto BackupAgent personalizzato facoltativo, è necessario assicurarsi di usare MAMBackupAgent o MAMBackupAgentHelper.[Optional] If you implemented an optional custom BackupAgent, you need to make sure to use MAMBackupAgent or MAMBackupAgentHelper. Vedere le sezioni seguenti.See the following sections. Valutare se usare MAMDefaultFullBackupAgent di Intune (descritto nel passaggio 1), che offre un semplice backup su Android M e versioni successive.Consider switching to using Intune's MAMDefaultFullBackupAgent (described in step 1) which provides easy back up on Android M and above.

  3. Quando si decide quale tipo di backup completo deve ricevere l'app (non filtrato, filtrato o nessuno) è necessario impostare l'attributo android:fullBackupContent su true, false o su una risorsa XML all'interno dell'applicazione.When you decide which type of full backup your app should receive (unfiltered, filtered, or none) you'll need to set the attribute android:fullBackupContent to true, false, or an XML resource in your app.

  4. È quindi necessario copiare il contenuto di android:fullBackupContent in un tag di metadati denominato com.microsoft.intune.mam.FullBackupContent nel manifesto.Then, you must copy whatever you put into android:fullBackupContent into a metadata tag named com.microsoft.intune.mam.FullBackupContent in the manifest.

    Esempio 1: se si vuole che l'app abbia backup completi senza esclusioni, impostare l'attributo android:fullBackupContent e il tag di metadati com.microsoft.intune.mam.FullBackupContent su true:Example 1: If you want your app to have full backups without exclusions, set both the android:fullBackupContent attribute and com.microsoft.intune.mam.FullBackupContent metadata tag to true:

    android:fullBackupContent="true"
    ...
    <meta-data android:name="com.microsoft.intune.mam.FullBackupContent" android:value="true" />  
    

    Esempio 2: se si vuole che l'app usi l'oggetto BackupAgent personalizzato e rifiuti esplicitamente i backup automatici completi conformi ai criteri di Intune, è necessario impostare l'attributo e il tag di metadati su false:Example 2: If you want your app to use its custom BackupAgent and opt out of full, Intune policy compliant, automatic backups, you must set the attribute and metadata tag to false:

    android:fullBackupContent="false"
    ...
    <meta-data android:name="com.microsoft.intune.mam.FullBackupContent" android:value="false" />  
    

    Esempio 3: se si vuole che l'app abbia backup completi in base a regole personalizzate definite in un file XML, impostare l'attributo e il tag di metadati sulla stessa risorsa XML:Example 3: If you want your app to have full backups according to your custom rules defined in an XML file, please set the attribute and metadata tag to the same XML resource:

    android:fullBackupContent="@xml/my_scheme"
    ...
    <meta-data android:name="com.microsoft.intune.mam.FullBackupContent" android:resource="@xml/my_scheme" />  
    

Backup di chiave/valoreKey/Value Backup

L'opzione di backup di chiave/valore è disponibile per tutte le API 8+ e carica i dati dell'app nel servizio di backup Android.The Key/Value Backup option is available to all APIs 8+ and uploads app data to the Android Backup Service. La quantità di dati per ogni utente dell'app è limitata a 5 MB.The amount of data per user of your app is limited to 5MB. Se si usa il backup di chiave/valore, è necessario usare un oggetto BackupAgentHelper o BackupAgent.If you use Key/Value Backup, you must use a BackupAgentHelper or a BackupAgent.

BackupAgentHelperBackupAgentHelper

BackupAgentHelper è più semplice da implementare rispetto a BackupAgent in termini sia di funzionalità Android native sia di integrazione MAM di Intune.BackupAgentHelper is easier to implement than BackupAgent both in terms of native Android functionality and Intune MAM integration. BackupAgentHelper consente allo sviluppatore di registrare interi file e preferenze condivise rispettivamente in un oggetto FileBackupHelper e SharedPreferencesBackupHelper, che vengono quindi aggiunti a BackupAgentHelper subito dopo la creazione.BackupAgentHelper allows the developer to register entire files and shared preferences to a FileBackupHelper and SharedPreferencesBackupHelper (respectively) which are then added to the BackupAgentHelper upon creation. Attenersi alla procedura seguente per usare BackupAgentHelper con MAM di Intune:Follow the steps below to use a BackupAgentHelper with Intune MAM:

  1. Per usare il backup di identità multiple con BackupAgentHelper, seguire la guida di Android per l'estensione di BackupAgentHelper.To utilize multi-identity backup with a BackupAgentHelper, follow the Android guide to Extending BackupAgentHelper.

  2. Fare in modo che la classe estenda l'equivalente MAM di BackupAgentHelper, FileBackupHelper e SharedPreferencesBackupHelper.Have your class extend the MAM equivalent of BackupAgentHelper, FileBackupHelper, and SharedPreferencesBackupHelper.

Classe AndroidAndroid class Equivalente MAMMAM equivalent
BackupAgentHelperBackupAgentHelper MAMBackupAgentHelperMAMBackupAgentHelper
FileBackupHelperFileBackupHelper MAMFileBackupHelperMAMFileBackupHelper
SharedPreferencesBackupHelperSharedPreferencesBackupHelper MAMSharedPreferencesBackupHelperMAMSharedPreferencesBackupHelper

Attenendosi a queste indicazioni sarà possibile implementare un processo di backup e ripristino di identità multiple.Following these guidelines will lead to a successful multi-identity backup and restore.

BackupAgentBackupAgent

Un oggetto BackupAgent consente di definire in modo molto più esplicito i dati di cui eseguire il backup.A BackupAgent allows you to be much more explicit about what data is backed up. Dato che lo sviluppatore è responsabile dell'implementazione, sono necessari altri passaggi per garantire una protezione appropriata dei dati da Intune.Because the developer is fairly responsible for the implementation, there are more steps required to ensure appropriate data protection from Intune. Poiché il maggior carico di lavoro ricade sullo sviluppatore, l'integrazione di Intune è leggermente più coinvolta.Since most of the work is pushed onto you, the developer, Intune integration is slightly more involved.

Integrare MAM:Integrate MAM:

  1. Leggere attentamente la guida di Android per il backup di chiave/valore e in particolare per l'estensione di BackupAgent per assicurarsi che l'implementazione di BackupAgent segua le linee guida Android.Please carefully read the Android guide for Key/Value Backup and specifically Extending BackupAgent to ensure your BackupAgent implementation follows Android guidelines.

  2. Fare in modo che la classe estenda MAMBackupAgent.Have your class extend MAMBackupAgent.

Backup di identità multiple:Multi-identity Backup:

  1. Prima di iniziare il backup, controllare che per i file o i buffer di dati di cui si prevede di eseguire il backup l'amministratore IT abbia consentito il backup in scenari con identità multiple.Before beginning your backup, check that the files or data buffers you plan to back up are indeed permitted by the IT administrator to be backed up in multi-identity scenarios. Per eseguire il controllo, è disponibile la funzione isBackupAllowed in MAMFileProtectionManager e MAMDataProtectionManager.We provide you with the isBackupAllowed function in MAMFileProtectionManager and MAMDataProtectionManager to determine this. Se per il file o il buffer di dati non è consentito il backup, non continuare a includere l'elemento nel backup.If the file or data buffer is not allowed to be backed up, then you should not continue including it in your backup.

  2. Se a un certo punto durante il backup si vuole eseguire il backup delle identità per i file controllati nel passaggio 1, è necessario chiamare backupMAMFileIdentity(BackupDataOutput data, File … files) con i file da cui si prevede di estrarre i dati.At some point during your backup, if you want to back up the identities for the files you checked in step 1, you must call backupMAMFileIdentity(BackupDataOutput data, File … files) with the files from which you plan to extract data. In questo modo, verranno automaticamente create entità di backup, che verranno scritte in BackupDataOutput .This will automatically create new backup entities and write them to the BackupDataOutput for you. Queste entità verranno utilizzate automaticamente al momento del ripristino.These entities will be automatically consumed upon restore.

Ripristino di identità multiple:Multi-identity Restore:

La guida al backup dei dati specifica un algoritmo generale per il ripristino dei dati dell'applicazione e fornisce un esempio di codice nella sezione relativa all'estensione di BackupAgent.The Data Backup guide specifies a general algorithm for restoring your application’s data and provides a code sample in the Extending BackupAgent section. Per un corretto ripristino di identità multiple, è necessario seguire la struttura generale fornita in questo esempio di codice con particolare attenzione a quanto segue:In order to have a successful multi-identity restore, you must follow the general structure provided in this code sample with special attention to the following:

  1. È necessario usare un ciclo while(data.readNextHeader())* per scorrere le entità di backup.You must utilize a while(data.readNextHeader())* loop to go through the backup entities.

  2. È necessario chiamare data.skipEntityData()* se data.getKey()* non corrisponde alla chiave scritta in onBackup.You must call data.skipEntityData()* if data.getKey()* does not match the key you wrote in onBackup. Senza questo passaggio, le operazioni di ripristino potrebbero non riuscire.Without performing this step, your restores may not succeed.

  3. Evitare di restituire il risultato mentre si utilizzano le entità di backup nel costrutto while(data.readNextHeader()), in quanto le entità scritte automaticamente andranno perse.Avoid returning while consuming backup entities in the while(data.readNextHeader()) construct, as the entities we automatically write will be lost.

  • Dove data è il nome della variabile locale per l'oggetto BackupDataInput passato all'app subito dopo il ripristino.Where data is the local variable name for the BackupDataInput that is passed to your app upon restore.

Identità multiple (facoltativo)Multi-identity (optional)

PanoramicaOverview

Per impostazione predefinita, Intune App SDK applicherà i criteri all'app nel suo complesso.By default, the Intune App SDK will apply policy to the app as a whole. Le identità multiple sono una funzionalità facoltativa di protezione delle app di Intune che è possibile abilitare per consentire l'applicazione dei criteri a un livello specifico per identità.Multi-identity is an optional Intune app protection feature which can be enabled to allow policy to be applied on a per-identity level. Ciò richiede una partecipazione dell'app molto più attiva rispetto ad altre funzionalità di protezione delle app.This requires significantly more app participation than other app protection features.

L'app deve informare l'SDK quando intende modificare l'identità attiva.The app must inform the SDK when it intends to change the active identity. In alcuni casi, l'SDK invia anche una notifica all'app quando è necessaria una modifica di identità.In some cases, the SDK will also notify the app when an identity change is required. Nella maggior parte dei casi, tuttavia, MAM non conosce i dati visualizzati nell'interfaccia utente o usati in un thread in un determinato momento e si basa sull'app per impostare l'identità corretta per evitare la perdita di dati.In most cases, however, MAM cannot know what data is being displayed in the UI or used on a thread at a given time and relies on the app to set the correct identity in order to avoid data leak. Nelle sezioni che seguono vengono descritti alcuni scenari specifici che richiedono azioni a livello di app.In the sections that follow, some particular scenarios which require app action will be called out.

Nota

Una mancanza di partecipazione dell'app corretta può causare perdite di dati e altri problemi di protezione.A lack of the correct app participation can result in data leaks and other security issues.

Una volta che l'utente registra il dispositivo o l'app, l'SDK registra questa identità e la considera l'identità primaria gestita di Intune.Once the user enrolls the device or the app, the SDK registers this identity and considers it the primary Intune managed identity. Gli altri utenti dell'app verranno trattati come non gestiti con impostazioni dei criteri senza restrizioni.Other users in the app will be treated as unmanaged, with unrestricted policy settings.

Nota

Attualmente è supportata solo un'identità gestita di Intune per volta.Currently, only one Intune managed identity is supported per device.

Si noti che un'identità viene semplicemente definita come stringa.Note that an identity is simply defined as a string. Le identità non fanno distinzione tra maiuscole e minuscole e le richieste all'SDK per un'identità possono non restituire un risultato in cui maiuscole e minuscole corrispondono a quelle usate in origine durante l'impostazione dell'identità.Identities are case-insensitive, and requests to the SDK for an identity may not return the same casing that was originally used when setting the identity.

Abilitazione di identità multipleEnabling Multi-identity

Per impostazione predefinita, tutte le app sono considerate app a identità singola.By default, all apps are considered to be single-identity apps. È possibile dichiarare che un'app supporta le identità multiple inserendo i metadati seguenti in AndroidManifest.xml.You can declare an app to be multi-identity aware by placing the following metadata in AndroidManifest.xml.

  <meta-data
    android:name="com.microsoft.intune.mam.MAMMultiIdentity"
    android:value="true" />

Impostazione dell'identitàSetting the Identity

Gli sviluppatori possono impostare l'identità dell'utente dell'app sui livelli seguenti con priorità decrescente:Developers can set the identity of the app user on the following levels in descending priority:

  1. A livello di threadThread level
  2. A livello di contesto (in genere attività)Context (generally Activity) level
  3. A livello di processoProcess level

Un'identità impostata a livello di thread ha una priorità maggiore rispetto a un'identità impostata a livello di contesto, che a sua volta ha una priorità maggiore rispetto a un'identità impostata a livello di processo.An identity set at the thread level supersedes an identity set at the Context level, which supersedes an identity set at the process level. Un'identità impostata a livello di contesto viene usata solo negli scenari associati appropriati.An identity set on a Context is only used in appropriate associated scenarios. Alle operazioni di I/O su file, ad esempio, non è associato un contesto.File IO operations, for example, do not have an associated Context. In genere, le app imposteranno l'identità del contesto su un'attività.Most commonly, apps will set the Context identity on an Activity. Un'app non deve visualizzare i dati per un'identità gestita, a meno che l'identità dell'attività non sia impostata sulla stessa identità.An app must not display data for a managed identity unless the Activity's identity is set to that same identity. In generale, l'identità a livello di processo è utile unicamente se l'app funziona solo con un singolo utente alla volta su tutti i thread.In general, the process-level identity is only useful if the app works only with a single user at a time on all threads. Per molte app potrebbe non essere necessaria.Many apps may not need to make use of it.

È possibile usare i metodi seguenti in MAMPolicyManager per impostare l'identità e recuperare i valori di identità impostati in precedenza.The following methods in MAMPolicyManager may be used to set the identity and retrieve the identity values previously set.

  public static void setUIPolicyIdentity(final Context context, final String identity, final MAMSetUIIdentityCallback mamSetUIIdentityCallback);

  public static String getUIPolicyIdentity(final Context context);

  public static MAMIdentitySwitchResult setProcessIdentity(final String identity);

  public static String getProcessIdentity();

  public static MAMIdentitySwitchResult setCurrentThreadIdentity(final String identity);

  public static String getCurrentThreadIdentity();

  /**
   * Get the currently applicable app policy. Same as
   * MAMComponents.get(AppPolicy.class). This method does
   * not take the context identity into account.
   */
  public static AppPolicy getPolicy();

  /**
  * Get the current app policy. This does NOT take the UI (Context) identity into account.
   * If the current operation has any context (e.g. an Activity) associated with it, use the overload below.
   */
  public static AppPolicy getPolicy(final Context context);


  public static AppPolicy getPolicyForIdentity(final String identity);

  public static boolean getIsIdentityManaged(final String identity);
Nota

È possibile cancellare l'identità dell'app impostandola su Null.You can clear the identity of the app by setting it to null.

Una stringa vuota può essere usata come un'identità che non avrà mai criteri di protezione delle app.The empty string may be used as an identity that will never have app protection policy.

RisultatiResults

Tutti i metodi usati per impostare l'identità restituiscono valori di risultato tramite MAMIdentitySwitchResult.All the methods used to set the identity report back result values via MAMIdentitySwitchResult. Possono essere restituiti quattro valori:There are four values that can be returned:

Valore restituitoReturn value ScenarioScenario
SUCCEEDEDSUCCEEDED La modifica dell'identità è riuscita.The identity change was successful.
NOT_ALLOWEDNOT_ALLOWED La modifica dell'identità non è consentita.The identity change is not allowed. La modifica dell'identità non è consentita.The identity change is not allowed. Si verifica in seguito al tentativo di impostare l'identità (contesto) dell'interfaccia utente quando è impostata un'identità diversa sul thread corrente.This occurs if an attempt is made to set the UI (Context) identity when a different identity is set on the current thread.
CANCELLEDCANCELLED L'utente ha annullato la modifica di identità, in genere premendo il pulsante Indietro in una richiesta di PIN o autenticazione.The user cancelled the identity change, generally by pressing the back button on a PIN or authentication prompt.
FAILEDFAILED La modifica dell'identità non è riuscita per un motivo non specificato.The identity change failed for an unspecified reason.

L'app deve verificare l'esito positivo di un cambio di identità prima di visualizzare o usare dati aziendali.The app must ensure that an identity switch is successful before displaying or using corporate data. Attualmente, i cambi di identità di processo e thread avranno sempre esito positivo per un'app con il supporto per identità multiple abilitato, tuttavia Microsoft si riserva il diritto di aggiungere le condizioni di errore.Currently, process and thread identity switches will always succeed for a multi-identity-enabled app, however we reserve the right to add failure conditions. Il cambio di identità dell'interfaccia utente potrebbe non riuscire per argomenti non validi, se genera un conflitto con l'identità del thread o se l'utente cancella i requisiti di avvio condizionale (ad esempio, premendo il pulsante Indietro nella schermata del PIN).The UI identity switch may fail for invalid arguments, if it would conflict with the thread identity, or if the user cancels out of conditional launch requirements (e.g. presses the back button on the PIN screen).

Nel caso dell'impostazione di un'identità a livello di contesto, il risultato viene restituito in modo asincrono.In the case of setting a Context identity, the result is reported asynchronously. Se il contesto è un'attività, l'SDK sa se la modifica dell'identità è riuscita solo dopo l'avvio condizionale, che potrebbe richiedere l'immissione di un PIN o di credenziali aziendali da parte dell'utente.If the Context is an Activity, the SDK doesn't know if the identity change succeeded until after conditional launch is performed -- which may require the user to enter a PIN or corporate credentials. È previsto che l'app implementi un oggetto MAMSetUIIdentityCallback per ricevere questo risultato. Per questo parametro è possibile passare Null.The app is expected to implement a MAMSetUIIdentityCallback to receive this result, you can pass null for this parameter.

    public interface MAMSetUIIdentityCallback {
        void notifyIdentityResult(MAMIdentitySwitchResult identitySwitchResult);
  }

È anche possibile impostare l'identità di un'attività direttamente tramite un metodo in MAMActivity invece di chiamare MAMPolicyManager.setUIPolicyIdentity.You can also set the identity of an activity directly through a method in MAMActivity instead of calling MAMPolicyManager.setUIPolicyIdentity. A tale scopo, usare il metodo seguente:Use following method to do so:

     public final void switchMAMIdentity(final String newIdentity);

È anche possibile eseguire l'override di un metodo in MAMActivity se si vuole che l'app riceva una notifica del risultato dei tentativi di modifica dell'identità per tale attività.You can also override a method in MAMActivity if you want the app to be notified of the result of attempts to change the identity of that activity.

    public void onSwitchMAMIdentityComplete(final MAMIdentitySwitchResult result);
Nota

Il cambio di identità potrebbe rendere necessario ricreare l'attività.Switching the identity may require recreating the activity. In questo caso, il callback onSwitchMAMIdentityComplete verrà recapitato alla nuova istanza dell'attività.In this case, the onSwitchMAMIdentityComplete callback will be delivered to the new instance of the activity.

Modifiche di identità impliciteImplicit Identity Changes

Oltre alla possibilità di impostare l'identità tramite l'app, l'identità di un thread o un contesto può cambiare anche in base all'ingresso di dati da un'altra app con supporto per Intune che usa criteri di protezione delle app.In addition to the app's ability to set the identity, a thread or a context's identity may change based on data ingress from another Intune-enlightened app that has app protection policy.

EsempiExamples

  1. Se un'attività viene avviata da un oggetto Intent inviato da un'altra app MAM, l'identità dell'attività verrà impostata in base all'identità effettiva nell'altra app al momento dell'invio di Intent.If an activity is launched from an Intent sent by another MAM app, the activity’s identity will be set based on the effective identity in the other app at the point the Intent was sent.

  2. Per i servizi, l'identità del thread verrà impostata in modo analogo per la durata di una chiamata di onStart o onBind.For services, the thread identity will be set similarly for the duration of an onStart or onBind call. Anche le chiamate all'oggetto Binder restituito da onBind impostano temporaneamente l'identità del thread.Calls into the Binder returned from onBind will also temporarily set the thread identity.

  3. Le chiamate a ContentProvider imposteranno l'identità del thread in modo analogo per la loro durata.Calls into a ContentProvider will similarly set the thread identity for their duration.

Inoltre, l'interazione dell'utente con un'attività può causare un cambio di identità implicito.In addition, user interaction with an activity may cause an implicit identity switch.

Esempio: se un utente annulla una richiesta di autenticazione durante l'esecuzione di Resume, il risultato è un passaggio implicito a un'identità vuota.Example: A user canceling out of an authorization prompt during Resume will result in an implicit switch to an empty identity.

L'app ha la possibilità di essere messa a conoscenza di queste modifiche e, se necessario, di impedirle.The app is given an opportunity to be made aware of these changes, and, if it must, the app can forbid them. MAMService e MAMContentProvider espongono il metodo seguente che può essere sottoposto a override dalle sottoclassi:MAMService and MAMContentProvider expose the following method that subclasses may override:

public void onMAMIdentitySwitchRequired(final String identity,
  final AppIdentitySwitchResultCallback callback);

Nella classe MAMActivity è presente un parametro aggiuntivo nel metodo:In the MAMActivity class , an additional parameter is present in the method:

public void onMAMIdentitySwitchRequired(final String identity,
  final AppIdentitySwitchReason reason,
  final AppIdentitySwitchResultCallback callback);
  • AppIdentitySwitchReason acquisisce l'origine del cambio implicito e può accettare i valori CREATE, RESUME_CANCELLED e NEW_INTENT.The AppIdentitySwitchReason captures the source of the implicit switch, and can accept the values CREATE, RESUME_CANCELLED, and NEW_INTENT. Il motivo RESUME_CANCELLED viene usato quando la ripresa di un'attività comporta la visualizzazione dell'interfaccia utente per l'immissione del PIN, per l'autenticazione o per altre esigenze di conformità e l'utente tenta di eliminare tale interfaccia, in genere usando il pulsante Indietro.The RESUME_CANCELLED reason is used when activity resume causes PIN, authentication, or other compliance UI to be displayed and the user attempts to cancel out of that UI, generally though use of the back button.

  • L'oggetto AppIdentitySwitchResultCallback è come segue:The AppIdentitySwitchResultCallback is as follows:

    public interface AppIdentitySwitchResultCallback {
        /**
         * @param result
         *            whether the identity switch can proceed.
         */
        void reportIdentitySwitchResult(AppIdentitySwitchResult result);
    }
    

    Dove AppIdentitySwitchResult è SUCCESS o FAILURE.Where AppIdentitySwitchResult is either SUCCESS or FAILURE.

Il metodo onMAMIdentitySwitchRequired viene chiamato per tutte le modifiche di identità implicite ad eccezione di quelle effettuate tramite un Binder restituito da MAMService.onMAMBind.The method onMAMIdentitySwitchRequired is called for all implicit identity changes except for those made through a Binder returned from MAMService.onMAMBind. Le implementazioni predefinite di onMAMIdentitySwitchRequired chiamano immediatamente:The default implementations of onMAMIdentitySwitchRequired immediately call:

  • reportIdentitySwitchResult(FAILURE) quando il motivo è RESUME_CANCELLED.reportIdentitySwitchResult(FAILURE) when the reason is RESUME_CANCELLED.

  • reportIdentitySwitchResult(SUCCESS) in tutti gli altri casi.reportIdentitySwitchResult(SUCCESS) in all other cases.

    Si prevede che la maggior parte delle app non abbia l'esigenza di bloccare o ritardare un cambio di identità in un modo diverso, ma se un'app deve farlo, è necessario prendere in considerazione i punti seguenti:It is not expected that most apps will need to block or delay an identity switch in a different manner, but if an app needs to do so, the following points must be considered:

    • Se un cambio di identità è bloccato, il risultato è lo stesso che si sarebbe avuto se le impostazioni di condivisione di Receive avessero vietato l'ingresso dei dati.If an identity switch is blocked, the result is the same as if Receive sharing settings had prohibited the data ingress.

    • Se un servizio è in esecuzione sul thread principale, è necessario chiamare reportIdentitySwitchResult in modo sincrono altrimenti il thread dell'interfaccia utente si blocca.If a Service is running on the main thread, reportIdentitySwitchResult must be called synchronously or the UI thread will hang.

    • Per la creazione dell'attività, onMAMIdentitySwitchRequired viene chiamato prima di onMAMCreate.For Activity creation, onMAMIdentitySwitchRequired will be called before onMAMCreate. Se l'app deve visualizzare l'interfaccia utente per determinare se consentire il cambio di identità, tale interfaccia utente deve essere visualizzata usando un'attività diversa.If the app must show UI to determine whether to allow the identity switch, that UI must be shown using a different activity.

    • In un'attività, quando viene richiesto il passaggio all'identità vuota con il motivo RESUME_CANCELLED, l'app deve modificare l'attività ripresa in modo da visualizzare dati coerenti con il cambio di identità.In an Activity, when a switch to the empty identity is requested with the reason as RESUME_CANCELLED, the app must modify the resumed activity to display data consistent with that identity switch. Se ciò non è possibile, l'app deve rifiutare il cambio e all'utente verrà chiesto di nuovo di conformarsi ai criteri per l'identità di ripresa, ad esempio con la visualizzazione della schermata per l'immissione del PIN dell'app.If this is not possible, the app should refuse the switch, and the user will be asked again to comply with policy for the resuming identity (e.g. by being presented with the app PIN entry screen).

      Nota

      Un'app con identità multiple riceverà sempre dati in arrivo sia da app gestite che non gestite.A multi-identity app will always receive incoming data from both managed and unmanaged apps. È responsabilità dell'app trattare i dati provenienti da identità gestite in modo gestito.It is the responsibility of the app to treat data from managed identities in a managed manner.

    Se un'identità richiesta è gestita (usare MAMPolicyManager.getIsIdentityManaged per controllare), ma l'app non è in grado di usare tale account (ad esempio, perché gli account, come gli account di posta elettronica, devono essere prima di tutto configurati nell'app), il cambio di identità deve essere rifiutato.If a requested identity is managed (use MAMPolicyManager.getIsIdentityManaged to check), but the app is not able to use that account (e.g. because accounts, such as email accounts, must be set up in the app first) then the identity switch should be refused.

Protezione dei fileFile Protection

A ogni file è associata un'identità al momento della creazione in base all'identità a livello di processo e thread.Every file has an identity associated with it at the time of creation, based on thread and process identity. Questa identità verrà usata sia per la crittografia dei file che per la cancellazione selettiva.This identity will be used for both file encryption and selective wipe. Verranno crittografati solo i file la cui identità è gestita e ha criteri che richiedono la crittografia.Only files whose identity is managed and has policy requiring encryption will be encrypted. La cancellazione selettiva predefinita dell'SDK cancellerà solo i file associati all'identità per cui è stata richiesta una cancellazione.The SDK's default selective functionality wipe will only wipe files associated with the managed identity for which a wipe has been requested. L'app può richiedere o modificare l'identità di un file usando la classe MAMFileProtectionManager.The app may query or change a file’s identity using the MAMFileProtectionManager class.

  public final class MAMFileProtectionManager {
  /**
       * Protect a file. This will synchronously trigger whatever protection is required for the 
         file, and will tag the file for future protection changes.

       *
       * @param identity
       *            Identity to set.
       * @param file
       *            File to protect.
       * @throws IOException
       *             If the file cannot be changed.
       */
      public static void protect(final File file, final String identity) throws IOException;

      /**
      * Protect a file obtained from a content provider. This is intended to be used for
      * sdcard (whether internal or removable) files accessed through the Storage Access Framework.
      * It may also be used with descriptors referring to private files owned by this app.
      * It is not intended to be used for files owned by other apps and such usage will fail. If
      * creating a new file via a content provider exposed by another MAM-integrated app, the new
      * file identity will automatically be set correctly if the ContentResolver in use was
      * obtained via a Context with an identity or if the thread identity is set.
      *
      * This will synchronously trigger whatever protection is required for the file, and will tag
      * the file for future protection changes. If an identity is set on a directory, it is set
      * recursively on all files and subdirectories. If MAM is operating in offline mode, this
      * method will silently do nothing.
      *
      * @param identity
      *       Identity to set.
      * @param file
      *       File to protect.
      *
      * @throws IOException
      *       If the file cannot be protected.

      */
      public static void protect(final ParcelFileDescriptor file, final String identity) throws IOException;

      /**
       * Get the protection info on a file.
       *
       * @param file
       *            File or directory to get information on.
       * @return File protection info, or null if there is no protection info.
       * @throws IOException
       *             If the file cannot be read or opened.
       */
      public static MAMFileProtectionInfo getProtectionInfo(final ParcelFileDescriptor file) throws IOException;

  }

  public interface MAMFileProtectionInfo {
      String getIdentity();
  }

Responsabilità dell'appApp Responsibility

MAM non può dedurre automaticamente una relazione tra i file in lettura e i dati visualizzati in una Activity.MAM cannot automatically infer a relationship between files being read and data being displayed in an Activity. L'app deve impostare l'identità dell'interfaccia utente in modo appropriato prima di visualizzare i dati aziendali,Apps must set the UI identity appropriately before displaying corporate data. inclusi i dati letti dai file.This includes data read from files. Se un file proviene dall'esterno dell'app (da un ContentProvider o letto da un percorso pubblicamente accessibile in scrittura), l'app deve tentare di determinare l'identità di file (usando MAMFileProtectionManager.getProtectionInfo) prima di visualizzare le informazioni lette dal file.If a file comes from outside the app (either from a ContentProvider or read from a publicly writable location), the app must attempt to determine the file identity (using MAMFileProtectionManager.getProtectionInfo) before displaying information read from the file. Se getProtectionInfo segnala un'identità non Null e non vuota, l'identità dell'interfaccia utente deve essere impostata in base a questa identità (usando MAMActivity.switchMAMIdentity o MAMPolicyManager.setUIPolicyIdentity).If getProtectionInfo reports a non-null, non-empty identity, the UI identity must be set to match this identity (using MAMActivity.switchMAMIdentity or MAMPolicyManager.setUIPolicyIdentity). Se il cambio di identità ha esito negativo, i dati dal file non devono essere visualizzati.If the identity switch fails, data from the file must not be displayed.

Il flusso potrebbe essere simile al seguente:An example flow might look something like the following:

  • L'utente seleziona un documento da aprire nell'appUser selects a document to open in the app
  • Durante il flusso aperto, prima della lettura dei dati dal disco, l'app conferma l'identità da usare per visualizzare il contenutoDuring the open flow, prior to reading data from disk, the app confirms the identity that should be used to display the content
    • Info MAMFileProtectionInfo = MAMFileProtectionManager.getProtectionInfo(docPath)MAMFileProtectionInfo info = MAMFileProtectionManager.getProtectionInfo(docPath)
    • if(Info) MAMPolicyManager.setUIPolicyIdentity (attività, info.getIdentity(), callback)if(info) MAMPolicyManager.setUIPolicyIdentity(activity, info.getIdentity(), callback)
    • L'app attende finché non viene restituito un risultato al callbackThe app waits until a result is reported to callback
    • Se il risultato restituito è un errore, l'app non visualizza il documento.If the reported result is a failure, the app does not display the document.
  • L'app si apre ed esegue il rendering del fileThe app opens and renders the file

Scenari offlineOffline Scenarios

La modalità offline influisce sull'aggiunta di tag di identità ai file.File identity tagging is sensitive to offline mode. Tenere in considerazione i punti seguenti:The following points should be taken into account:

  • Se l'app Portale aziendale non è installata, non è possibile assegnare tag di identità ai file.If the Company Portal is not installed, files cannot be identity-tagged.

  • Se l'app Portale aziendale è installata, ma non ha criteri MAM di Intune, non è possibile assegnare tag di identità ai file in modo affidabile.If the Company Portal is installed, but the app does not have Intune MAM policy, files cannot be reliably tagged with identity.

  • Quando diventa disponibile la possibilità di assegnare tag di identità ai file, tutti i file creati in precedenza vengono considerati come personali/non gestiti (appartenenti all'identità con stringa vuota), a meno che l'app non sia stata installata in precedenza come app gestita con identità singola. In questo caso, i file vengono considerati appartenenti all'utente registrato.When file identity tagging becomes available, all previously created files are treated as personal/unmanaged (belonging to the empty-string identity) unless the app was previously installed as a single-identity managed app in which case they are treated as belonging to the enrolled user.

Protezione delle directoryDirectory Protection

Le directory possono essere protette usando lo stesso metodo protect usato per proteggere i file.Directories may be protected using the same protect method used to protect files. Si noti che la protezione delle directory si applica in modo ricorsivo a tutti i file e le sottodirectory presenti nella directory e ai nuovi file creati all'interno della directory.Please note that directory protection applies recursively to all files and subdirectories contained in the directory, and to new files created within the directory. Poiché la protezione delle directory viene applicata in modo ricorsivo, la chiamata di protect può richiedere parecchio tempo per il completamento in caso di directory di dimensioni molto grandi.Because directory protection is applied recursively, the protect call can take some time to complete for very large directories. Per questo motivo, è consigliabile che le app che applicano la protezione a una directory contenente un numero elevato di file eseguano protect in modo asincrono in un thread in background.For that reason, apps applying protection to a directory that contains a large number of files might wish to run protect asynchronously on a background thread.

Protezione datiData Protection

Non è possibile assegnare un tag a un file appartenente a più identità.It is not possible to tag a file as belonging to multiple identities. Le app che devono archiviare dati appartenenti a utenti diversi nello stesso file possono farlo manualmente, usando le funzionalità fornite da MAMDataProtectionManager.Apps that must store data belonging to different users in the same file can do so manually, using the features provided by MAMDataProtectionManager. Questo permette all'app di crittografare i dati e associarli a un utente specifico.This allows the app to encrypt data and tie it to a particular user. I dati crittografati sono adatti per l'archiviazione su disco in un file.The encrypted data is suitable for storing to disk in a file. È possibile recuperare i dati associati all'identità e i dati possono essere decrittografati in un secondo momento.You can query the data associated with the identity and the data can be unecrypted later.

Le app che usano MAMDataProtectionManager devono implementare un ricevitore per la notifica MANAGEMENT_REMOVED.Apps which make use of MAMDataProtectionManager should implement a receiver for the MANAGEMENT_REMOVED notification. Dopo il completamento della notifica, i buffer protetti tramite questa classe non saranno più leggibili se la crittografia dei file è stata abilitata quando i buffer erano protetti.After this notification completes, buffers which were protected via this class will no longer be readable if file encryption was enabled when the buffers were protected. Un'app può risolvere questa situazione chiamando MAMDataProtectionManager.unprotect su tutti i buffer durante la notifica.An app can remediate this situation by calling MAMDataProtectionManager.unprotect on all buffers during this notification. Si noti che è anche possibile chiamare protect durante questa notifica, se lo si desidera per mantenere le informazioni di identità. Durante la notifica la crittografia viene sicuramente disabilitata.Note that it is also safe to call protect during this notification if it is desired to preserve identity information -- encryption is guaranteed to be disabled during the notification.


public final class MAMDataProtectionManager {
    /**
     * Protect a stream. This will return a stream containing the protected
     * input.
     *
     * @param identity
     *            Identity to set.
     * @param input
     *            Input data to protect, read sequentially. This function
     *            will change the position of the stream but may not have
     *            read the entire stream by the time it returns. The
     *            returned stream will wrap this one. Calls to read on the
     *            returned stream may cause further reads on the original
     *            input stream. Callers should not expect to read directly
     *            from the input stream after passing it to this method.
     *            Calling close on the returned stream will close this one.
     * @return Protected input data.
     * @throws IOException
     *             If the data could not be protected
     */
    public static InputStream protect(final InputStream input, final String identity);

    /**
     * Protect a byte array. This will return protected bytes.
     *
     * @param identity
     *            Identity to set.
     * @param input
     *            Input data to protect.
     * @return Protected input data.
     * @throws IOException
     *             If the data could not be protected
     */
    public static byte[] protect(final byte[] input, final String identity) throws IOException;

    /**
     * Unprotect a stream. This will return a stream containing the
     * unprotected input.
     *
     * @param input
     *            Input data to protect, read sequentially.
     * @return Protected input data.
     * @throws IOException
     *             If the data could not be unprotected
     */
    public static InputStream unprotect(final InputStream input) throws IOException;

    /**
     * Unprotect a byte array. This will return unprotected bytes.
     *
     * @param input
     *            Input data to protect.
     * @return Protected input data.
     * @throws IOException
     *             If the data could not be unprotected
     */
    public static byte[] unprotect(final byte[] input) throws IOException;

    /**
     * Get the protection info on a stream.
     *
     * @param input
     *            Input stream to get information on. Either this input
     *            stream must have been returned by a previous call to
     *            protect OR input.markSupported() must return true.
     *            Otherwise it will be impossible to get protection info
     *            without advancing the stream position. The stream must be
     *            positioned at the beginning of the protected data.
     * @return Data protection info, or null if there is no protection
     *            info.
     * @throws IOException
     *             If the input cannot be read.
     */
    public static MAMDataProtectionInfo getProtectionInfo(final InputStream input) throws IOException;

    /**
     * Get the protection info on a stream.
     *
     * @param input
     *            Input bytes to get information on. These must be bytes
     *            returned by a previous call to protect() or a copy of
     *            such bytes.
     * @return Data protection info, or null if there is no protection
     *            info.
     * @throws IOException
     *             If the input cannot be read.
     */
    public static MAMDataProtectionInfo getProtectionInfo(final byte[] input) throws IOException;
}

Provider di contenutoContent Providers

Se l'app fornisce dati aziendali diversi da ParcelFileDescriptor tramite un oggetto ContentProvider, l'app deve chiamare il metodo isProvideContentAllowed(String) in MAMContentProvider, passando l'UPN (nome dell'entità utente) dell'identità del proprietario per il contenuto.If the app provides corporate data other than a ParcelFileDescriptor through a ContentProvider, the app must call the method isProvideContentAllowed(String) in MAMContentProvider, passing the owner identity's UPN (user principal name) for the content. Se questa funzione restituisce false, il contenuto non può essere restituito al chiamante.If this function returns false, the content may not be returned to the caller. I descrittori di file restituiti tramite un provider di contenuti vengono gestiti automaticamente in base all'identità del file.File descriptors returned through a content provider are handled automatically based on the file identity.

Cancellazione selettivaSelective Wipe

Se un'app esegue la registrazione per la notifica WIPE_USER_DATA, non potrà usufruire dei vantaggi del comportamento di cancellazione selettiva predefinito dell'SDK.If an app registers for the WIPE_USER_DATA notification, it will not receive the benefit of the SDK's default selective wipe behavior. Per le app che supportano identità multiple, questa perdita può essere più significativa in quanto la cancellazione selettiva predefinita di MAM cancellerà solo i file la cui identità è interessata da una cancellazione.For multi-identity aware apps, this loss may be more significant since MAM default selective wipe will wipe only files whose identity is targeted by a wipe.

Se un'applicazione che supporta identità multiple vuole che venga eseguita la cancellazione selettiva predefinita di MAM e vuole eseguire operazioni personalizzate sulla cancellazione, deve eseguire la registrazione per le notifiche WIPE_USER_AUXILIARY_DATA.If a multi-identity aware application wishes MAM default selective wipe to be done and wishes to perform its own actions on wipe, it should register for WIPE_USER_AUXILIARY_DATA notifications. Questa notifica verrà inviata immediatamente dall'SDK prima di eseguire la cancellazione selettiva predefinita di MAM.This notification will be sent immediately by the SDK before it performs the MAM default selective wipe. Un'app non deve mai eseguire la registrazione sia per WIPE_USER_DATA che per WIPE_USER_AUXILIARY_DATA.An app should never register for both WIPE_USER_DATA and WIPE_USER_AUXILIARY_DATA.

Abilitazione della configurazione di destinazione MAM per le applicazioni Android (facoltativo)Enabling MAM targeted configuration for your Android applications (optional)

Le coppie chiave-valore specifiche dell'applicazione possono essere configurate nella console di Intune.Application-specific key-value pairs may be configured in the Intune console. Queste coppie chiave-valore non vengono interpretate da Intune, ma vengono semplicemente passate all'app.These key-value pairs are not interpreted by Intune at all, but are simply passed on to the app. Le applicazioni per le quali si vuole ricevere questo tipo di configurazione possono usare le classi MAMAppConfigManager e MAMAppConfig a tale scopo.Applications which want to receive such configuration can use the MAMAppConfigManager and MAMAppConfig classes to do so. Se più criteri sono destinati alla stessa app, potrebbero essere presenti più valori in conflitto per la stessa chiave.If multiple policies are targeted at the same app, there may be multiple conflicting values available for the same key.

EsempioExample

MAMAppConfigManager configManager = MAMComponents.get(MAMAppConfigManager.class);
String identity = "user@contoso.com"
MAMAppConfig appConfig = configManager.getAppConfig(identity);
LOGGER.info("App Config Data = " + (appConfig == null ? "null" : appConfig.getFullData()));
String valueToUse = null;
if (appConfig.hasConflict("foo")) {
    List<String> values = appConfig.getAllStringsForKey("foo");
    for (String value : values) {
        if (isCorrectValue(value)) {
            valueToUse = value;
        }
    }
} else {
    valueToUse = appConfig.getStringForKey("foo", MAMAppConfig.StringQueryType.Any);
}
LOGGER.info("Found value " + valueToUse);

Riferimento MAMAppConfigMAMAppConfig Reference

public interface MAMAppConfig {
    /**
     * Conflict resolution types for Boolean values.
     */
    enum BooleanQueryType {
        /**
         * In case of conflict, arbitrarily picks one. This is not guaranteed to return the same value every time.
         */
        Any,
        /**
         * In case of conflict, returns true if any of the values are true.
         */
        Or,
        /**
         * In case of conflict, returns false if any of the values are false.
         */
        And
    }

    /**
     * Conflict resolution types for integer and double values.
     */
    enum NumberQueryType {
        /**
         * In case of conflict, arbitrarily picks one. This is not guaranteed to return the same value every time.
         */
        Any,
        /**
         * In case of conflict, returns the minimum Integer.
         */
        Min,
        /**
         * In case of conflict, returns the maximum Integer.
         */
        Max
    }

    /**
     * Conflict resolution types for Strings.
     */
    enum StringQueryType {
        /**
         * In case of conflict, arbitrarily picks one. This is not guaranteed to return the same value every time.
         */
        Any,
        /**
         * In case of conflict, returns the first result ordered alphabetically.
         */
        Min,
        /**
         * In case of conflict, returns the last result ordered alphabetically.
         */
        Max
    }

    /**
     * Retrieve the List of Dictionaries containing all the custom
     *  config data sent by the MAMService. This will return every
     * Application Configuration setting available for this user, one
     *  mapping for each policy applied to the user.
     */
    List<Map<String, String>> getFullData();

    /**
     * Returns true if there is more than one targeted custom config setting for the key provided. 
     */
    boolean hasConflict(String key);

    /**
     * @return a Boolean value for the given key if it can be coerced into a Boolean, or 
     * null if none exists or it cannot be coerced.
     */
    Boolean getBooleanForKey(String key, BooleanQueryType queryType);

    /**
     * @return a Long value for the given key if it can be coerced into a Long, or null if none exists or it cannot be coerced.
     */
    Long getIntegerForKey(String key, NumberQueryType queryType);

    /**
     * @return a Double value for the given key if it can be coerced into a Double, or null if none exists or it cannot be coerced.
     */
    Double getDoubleForKey(String key, NumberQueryType queryType);

    /**
     * @return a String value for the given key, or null if none exists.
     */
    String getStringForKey(String key, StringQueryType queryType);

    /**
     * Like getBooleanForKey except returns all values if multiple are present.
     */
    List<Boolean> getAllBooleansForKey(String key);

    /**
     * Like getIntegerForKey except returns all values if multiple are present.
     */
    List<Long> getAllIntegersForKey(String key);

    /**
     * Like getDoubleForKey except returns all values if multiple are present.
     */
    List<Double> getAllDoublesForKey(String key);

    /**
     * Like getStringForKey except returns all values if multiple are present.
     */
    List<String> getAllStringsForKey(String key);
}

NotificaNotification

La configurazione dell'app aggiunge un nuovo tipo di notifica:App config adds a new notification type:

  • REFRESH_APP_CONFIG: questa notifica viene inviata in una MAMUserNotification e informa l'app che sono disponibili nuovi dati di configurazione dell'app.REFRESH_APP_CONFIG: This notification is sent in a MAMUserNotification and informs the app that new app config data is available.

Per altre informazioni sulle funzionalità dell'API Graph relative ai valori di configurazione MAM di destinazione, vedere Configurazione MAM di destinazione di riferimento per l'API Graph.For more information about the capabilities of the Graph API with respect to the MAM targeted configuration values, see Graph API Reference MAM Targeted Config.

Per altre informazioni su come creare un criterio di configurazione dell'app di destinazione MAM in Android, vedere la sezione relativa alla configurazione di app di destinazione MAM in Come usare i criteri di configurazione delle app di Microsoft Intune per Android.For more information about how to create a MAM targeted app configuration policy in Android, see the section on MAM targeted app config in How to use Microsoft Intune app configuration policies for Android.

Personalizzazione dello stile (facoltativo)Style Customization (optional)

Le viste generate da MAM SDK possono essere personalizzate visivamente per ottenere una maggiore corrispondenza con l'app in cui sono integrate.Views generated by the MAM SDK can be visually customized to more closely match the app in which it is integrated. È possibile personalizzare i colori primari, secondari e di sfondo, oltre che le dimensioni del logo dell'app.You can customize primary, secondary, and background colors, as well as the size of the app logo. La personalizzazione dello stile è facoltativa e, se non viene configurato uno stile personalizzato, verranno usati i valori predefiniti.This style customization is optional and defaults will be used if no custom style is configured.

Modalità di personalizzazioneHow to customize

Per applicare le modifiche dello stile alle viste MAM di Intune, è prima necessario creare un file XML di override dello stile.In order to have style changes apply to the Intune MAM views, you must first create a style override XML file. Questo file deve essere inserito nella directory "/res/xml" dell'app e può avere un nome qualsiasi.This file should be placed in the “/res/xml” directory of your app and you may name it whatever you like. Di seguito è riportato un esempio del formato necessario per questo file.Below is an example of the format this file needs to follow.

<?xml version="1.0" encoding="utf-8"?>
<styleOverrides>
    <item
        name="foreground_color"
        resource="@color/red"/>
    <item
        name="accent_color"
        resource="@color/blue"/>
    <item
        name="background_color"
        resource="@color/green"/>
    <item
        name="logo_image"
        resource="@drawable/app_logo"/>
</styleOverrides>

È necessario riutilizzare le risorse già presenti all'interno dell'app.You must reuse resources that already exist within your app. È ad esempio necessario definire il colore verde nel file colors.xml e farvi riferimento qui.For example, you must define the color green in the colors.xml file and reference it here. Non è possibile usare il codice colore esadecimale "#0000ff".You cannot use the Hex color code “#0000ff." Le dimensioni massime per il logo dell'app sono di 110 DIP (dp).The maximum size for the app logo is 110 dip (dp). È possibile usare un'immagine del logo più piccola, ma rispettando le dimensioni massime si otterranno risultati migliori.You may use a smaller logo image, but adhering to the maximum size will yield the best looking results. Se si supera il limite di 110 DIP, l'immagine verrà ridotta con una possibile sfocatura.If you exceed the 110 dip limit, the image will scale down and possibly cause blurring.

Di seguito è riportato l'elenco completo degli attributi di stile consentiti, degli elementi dell'interfaccia utente da essi controllati, dei nomi di elemento degli attributi XML e dei tipi di risorsa previsti per ognuno di essi.Below is the complete list of allowed style attributes, the UI elements they control, their XML attribute item names, and the type of resource expected for each.

Attributo di stileStyle attribute Elementi dell'interfaccia utente interessatiUI elements affected Nome dell'elemento dell'attributoAttribute item name Tipo di risorsa previstoExpected resource type
Colore di sfondoBackground color Colore di sfondo della schermata del PINPIN screen background color
Colore di riempimento della casella del PINPIN box fill color
background_colorbackground_color ColoreColor
Colore primo pianoForeground color Colore del testo in primo pianoForeground text color
Bordo della casella del PIN nello stato predefinitoPIN box border in default state
Caratteri (compresi i caratteri offuscati) nella casella del PIN quando l'utente immette un PINCharacters (including obfuscated characters) in PIN box when user enters a PIN
foreground_colorforeground_color ColoreColor
Colore principaleAccent color Bordo della casella del PIN quando la casella è evidenziataPIN box border when highlighted
Collegamenti ipertestualiHyperlinks
accent_coloraccent_color ColoreColor
Logo dell'appApp logo Icona grande visualizzata nella schermata del PIN dell'app IntuneLarge icon that appears in the Intune app PIN screen logo_imagelogo_image Risorsa drawableDrawable

LimitazioniLimitations

Limitazioni relative alle dimensioni dei fileFile Size limitations

Per codebase di grandi dimensioni eseguite senza ProGuard, le limitazioni del formato di file eseguibile Dalvik diventano un problema.For large code bases that run without ProGuard, the limitations of the Dalvik executable file format become an issue. In particolare, possono essere previste le limitazioni seguenti:Specifically, the following limitations may occur:

  1. Limite a 65.000 per i campi.The 65K limit on fields.
  2. Limite a 65.000 per i metodi.The 65K limit on methods.

Limitazioni relative all'applicazione di criteriPolicy enforcement limitations

  • Acquisizione schermo: l'SDK non è in grado di applicare un nuovo valore dell'impostazione di acquisizione schermo nelle attività passate attraverso Activity.onCreate.Screen Capture: The SDK is unable to enforce a new screen capture setting value in Activities that have already gone through Activity.onCreate. Questo limite può provocare un periodo di tempo in cui l'app è stata configurata per la disabilitazione degli screenshot, ma è comunque possibile acquisire screenshot.This can result in a period of time where the app has been configured to disable screenshots but screenshots can still be taken.

  • Uso di resolver di contenuto: i criteri di trasferimento o ricezione di Intune possono bloccare interamente o parzialmente l'uso di un resolver di contenuto per accedere al provider di contenuti in un'altra app.Using Content Resolvers: The "transfer or receive" Intune policy may block or partially block the use of a content resolver to access the content provider in another app. Questo comportamento può far sì che i metodi ContentResolver restituiscano null o generino un valore di errore. Ad esempio, openOutputStream genera FileNotFoundException se è bloccato.This will cause ContentResolver methods to return null or throw a failure value (e.g. openOutputStream will throw FileNotFoundException if blocked). L'app può determinare se un errore di scrittura dei dati tramite un resolver di contenuto è stato provocato dai criteri (o verrebbe provocato dai criteri) effettuando questa chiamata:The app can determine whether a failure to write data through a content resolver was caused by policy (or would be caused by policy) by making the call:

    MAMPolicyManager.getPolicy(currentActivity).getIsSaveToLocationAllowed(contentURI);
    

    o se non è presente alcuna attività associataor if there is no associated activity

    MAMPolicyManager.getPolicy().getIsSaveToLocationAllowed(contentURI);
    

    In quest'ultimo caso, è necessario prestare particolare attenzione alle app che supportano le identità multiple per impostare l'identità del thread in modo appropriato (o passare a un'identità esplicita per la chiamata getPolicy).In this second case, multi-identity apps must take care to set the thread identity appropriately (or pass an explicit identity to the getPolicy call).

Servizi esportatiExported services

Il file AndroidManifest.xml incluso in Intune App SDK contiene MAMNotificationReceiverService, che deve essere un servizio esportato per consentire al Portale aziendale di inviare notifiche a un'app abilitata.The AndroidManifest.xml file included in the Intune App SDK contains MAMNotificationReceiverService, which must be an exported service to allow the Company Portal to send notifications to an enlightened app. Il servizio verifica il chiamante per garantire che l'invio di notifiche sia consentito solo all'app Portale aziendale.The service checks the caller to ensure that only the Company Portal is allowed to send notifications.

Aspettative del consumer di SDKExpectations of the SDK consumer

Intune SDK mantiene il contratto fornito dall'API Android, ma è possibile che vengano generate condizioni di errore più frequentemente come conseguenza dell'applicazione dei criteri.The Intune SDK maintains the contract provided by the Android API, though failure conditions may be triggered more frequently as a result of policy enforcement. Queste procedure consigliate per Android riducono la probabilità di errore:These Android best practices will reduce the likelihood of failure:

  • Le funzioni di Android SDK che possono restituire Null hanno una maggiore probabilità di essere Null.Android SDK functions that may return null have a higher likelihood of being null now. Per ridurre al minimo i problemi, assicurarsi che i controlli dei valori Null vengano eseguiti nei punti corretti.To minimize issues, ensure that null checks are in the right places.

  • Le funzionalità che è possibile controllare devono essere controllate tramite le rispettive API di sostituzione MAM.Features that can be checked for must be checked for through their MAM replacement APIs.

  • Tutte le funzioni derivate devono effettuare chiamate tramite le rispettive versioni delle superclassi.Any derived functions must call through to their super class versions.

  • Evitare un uso ambiguo di qualsiasi API.Avoid use of any API in an ambiguous way. L'uso di Activity.startActivityForResult senza controllare requestCode causa ad esempio un comportamento anomalo.For example, using Activity.startActivityForResult without checking the requestCode will cause strange behavior.

  • Tutti i progetti di libreria devono condividere lo stesso elemento android:package ogni volta che è possibile.All library projects should share the same android:package where possible. Ciò non comporta errori sporadici in fase di esecuzione, ma è esclusivamente un problema in fase di compilazione.This will not sporadically fail in run-time; this is purely a build-time problem. Nelle versioni più recenti di Intune App SDK verranno rimossi alcuni aspetti ridondanti.Newer versions of the Intune App SDK will remove some of the redundancy.

  • Usare gli strumenti di compilazione di Android SDK più recenti.Use the newest Android SDK build tools.

  • Rimuovere tutte le librerie non necessarie e non in uso, ad esempio android.support.v4.Remove all unnecessary and unused libraries (e.g. android.support.v4)

Per inviare commenti e suggerimenti sul prodotto, visita la pagina Intune Feedback