Fonctionnement

L'API client permet de contrôler de manière programmatique les appareils et la configuration pour l'enregistrement sans contact Android. Ce document présente l'API pour les fournisseurs de gestion de la mobilité en entreprise (EMM) et les développeurs informatiques d'entreprise. Après avoir lu ce document, vous devriez comprendre les principales ressources utilisées dans l'API et la manière dont elles interagissent. Si vous débutez avec l'enregistrement sans contact, lisez la courte introduction à android.com.

Présentation

L'API client aide les entreprises qui achètent des appareils Android d'enregistrement sans contact. Votre application ou outil peut aider les administrateurs informatiques à effectuer les opérations suivantes:

  • Créer, modifier et supprimer des configurations de provisionnement
  • Appliquez une configuration à un appareil ou supprimez-en une.
  • Sélectionnez une configuration par défaut pour tous les appareils ajoutés à l'enregistrement sans contact à l'avenir.

Grâce à cette API, les administrateurs informatiques peuvent également annuler l'enregistrement d'appareils dans le cadre de l'enregistrement sans contact. Pour gérer les utilisateurs de leur organisation ou accepter les conditions d'utilisation, les administrateurs informatiques utilisent le portail d'enregistrement sans contact.

Voici quelques utilisateurs types de cette API:

  • Les fournisseurs EMM ajoutent la prise en charge de l'enregistrement sans contact à leur console.
  • Les développeurs informatiques d'entreprise qui créent des outils pour automatiser les tâches d'enregistrement sans contact.

Principales ressources

Les configurations et les appareils sont les principales ressources que vous utilisez dans l'API. Elle peut également créer des configurations et des appareils à l'aide du portail d'enregistrement sans contact.

Relation entre l'appareil et le service client

Configuration
Les administrateurs informatiques définissent les options de provisionnement des appareils à l'aide d'une configuration. Les configurations incluent les règles EMM pour les appareils mobiles et les coordonnées qui s'affichent pour aider les utilisateurs. Les configurations sont au cœur de l'API. Vous les utilisez donc dans de nombreuses méthodes. Pour en savoir plus, consultez la section Configurations ci-dessous.
Appareil
Appareil Android compatible avec l'enregistrement sans contact qu'une entreprise a acheté auprès de son revendeur. Appliquez une configuration pour inclure l'appareil dans l'enregistrement sans contact. Les appareils disposent d'un ID matériel et de métadonnées associées. Pour en savoir plus, consultez la section Appareils ci-dessous.
DPC
Référence en lecture seule au DPC d'un EMM (outil de contrôle des règles relatives aux appareils). Ajoutez un DPC à une configuration afin de sélectionner la solution EMM pour les appareils. Tous les DPC répertoriés par l'API sont compatibles avec l'enregistrement sans contact et sont disponibles dans Google Play. Pour en savoir plus, consultez Dpc.

Pour répertorier toutes les méthodes et ressources d'API que votre application peut utiliser, consultez la documentation de référence de l'API.

Configurations

La ressource d'API Configuration combine les éléments suivants:

  • Le DPC de l'EMM installé sur les appareils.
  • Règles EMM appliquées aux appareils
  • Coordonnées affichées sur l'appareil pour aider les utilisateurs lors de la configuration

Grâce à l'API, votre application peut gérer les configurations pour les administrateurs informatiques. Appelez l'API pour extraire, créer, mettre à jour et supprimer des configurations. L'exemple ci-dessous montre comment créer une configuration:

Java

// Add metadata to help the device user during provisioning.
Configuration configuration = new Configuration();
configuration.setConfigurationName("Sales team");
configuration.setCompanyName("XYZ Corp.");
configuration.setContactEmail("it-support@example.com");
configuration.setContactPhone("+1 (800) 555-0112");
configuration.setCustomMessage("We're setting up your phone. Call or email for help.");

// Set the DPC that zero-touch enrollment downloads and installs from Google Play.
configuration.setDpcResourcePath(dpc.getName());

// Set the JSON-formatted EMM provisioning extras that are passed to the DPC.
configuration.setDpcExtras("{"
      + "\"android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED\":true,"
      + "\"android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE\":{"
      + "\"default_min_password_length\":6,"
      + "\"company_name\":\"XYZ Corp\","
      + "\"management_server\":\"emm.example.com\","
      + "\"terms_url\":\"https://www.example.com/policies/terms/\","
      + "\"allowed_user_domains\":\"[\\\"example.com\\\", \\\"example.org\\\"]\""
      + "}"
      + "}");

// Create the new configuration on the server.
AndroidProvisioningPartner.Customers.Configurations.Create request =
      service.customers().configurations().create(customerAccount, configuration);
Configuration response = request.execute();

.NET

// Add metadata to help the device user during provisioning.
Configuration configuration = new Configuration
{
    ConfigurationName = "Sales team",
    CompanyName = "XYZ Corp.",
    ContactEmail = "it-support@example.com",
    ContactPhone = "+1 (800) 555-0112",
    CustomMessage = "We're setting up your phone. Call or email for help."
};

// Set the DPC that zero-touch enrollment downloads and installs from Google Play.
configuration.DpcResourcePath = dpc.Name;

// Set the JSON-formatted EMM provisioning extras that are passed to the DPC.
configuration.DpcExtras = @"{
    ""android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED"":true,
    ""android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE"":{
    ""default_min_password_length"":6,
    ""company_name"":""XYZ Corp"",
    ""management_server"":""emm.example.com"",
    ""terms_url"":""https://www.example.com/policies/terms/"",
    ""allowed_user_domains"":""[\""example.com\"", \""example.org\""]""
  }
}";

// Create the new configuration on the server.
var request = service.Customers.Configurations.Create(configuration, customerAccount);
var response = request.Execute();

Python

# Add metadata to help the device user during provisioning.
configuration = {
    'configurationName': 'Sales team',
    'companyName': 'XYZ Corp.',
    'contactEmail': 'it-support@example.com',
    'contactPhone': '+1 (800) 555-0112',
    'customMessage': 'We\'re setting up your phone. Call or email for help.'}

# Set the DPC that zero-touch enrollment installs from Google Play.
configuration['dpcResourcePath'] = dpc['name']

# Set the JSON-formatted EMM provisioning extras that are passed to the DPC.
configuration['dpcExtras'] = '''{
    "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED":true,
    "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE":{
      "default_min_password_length":6,
      "company_name":"XYZ Corp",
      "management_server":"emm.example.com",
      "terms_url":"https://www.example.com/policies/terms/",
      "allowed_user_domains":"[\\"example.com\\", \\"example.org\\"]"}
}'''

# Create the new configuration on the server.
response = service.customers().configurations().create(
    parent=customer_account, body=configuration).execute()

Lorsque vous mettez à jour une configuration à l'aide de l'API patch, n'oubliez pas d'inclure le masque de champ ou une valeur pour chaque champ que vous ne souhaitez pas définir sur null. Consultez la section Configurations par défaut ci-dessous pour obtenir un exemple de mise à jour efficace d'une configuration.

Supprimer les configurations

Vous ne pouvez pas supprimer une configuration si elle est toujours appliquée aux appareils. Si vous essayez de supprimer une configuration en cours d'utilisation, la méthode API renvoie un code d'état HTTP 400 Bad Request et un message expliquant le nombre d'appareils qui utilisent cette configuration. Appelez customers.devices.removeConfiguration pour supprimer la configuration des appareils avant de réessayer.

Configurations par défaut

L'enregistrement sans contact fonctionne mieux lorsqu'une entreprise définit une configuration par défaut qui s'applique à tous les nouveaux appareils qu'elle achète. Envisagez de demander aux administrateurs informatiques de définir une configuration par défaut si aucune configuration n'est définie. L'exemple ci-dessous montre comment faire d'une configuration existante la valeur par défaut en définissant isDefault sur true:

Java

// Send minimal data with the request. Just the 2 required fields.
// targetConfiguration is an existing configuration that we want to make the default.
Configuration configuration = new Configuration();
configuration.setIsDefault(true);
configuration.setConfigurationId(targetConfiguration.getConfigurationId());

// Call the API, including the FieldMask to avoid setting other fields to null.
AndroidProvisioningPartner.Customers.Configurations.Patch request = service
      .customers()
      .configurations()
      .patch(targetConfiguration.getName(), configuration);
request.setUpdateMask("isDefault");
Configuration results = request.execute();

.NET

// Send minimal data with the request. Just the 2 required fields.
// targetConfiguration is an existing configuration that we want to make the default.
Configuration configuration = new Configuration
{
    IsDefault = true,
    ConfigurationId = targetConfiguration.ConfigurationId,
};

// Call the API, including the FieldMask to avoid setting other fields to null.
var request = service.Customers.Configurations.Patch(configuration,
                                                     targetConfiguration.Name);
request.UpdateMask = "IsDefault";
Configuration results = request.Execute();

Python

# Send minimal data with the request. Just the 2 required fields.
# target_configuration is an existing configuration we'll make the default.
configuration = {
    'isDefault': True,
    'configurationId': target_configuration['configurationId']}

# Call the API, including the FieldMask to avoid setting other fields to null.
response = service.customers().configurations().patch(
    name=target_configuration['name'],
    body=configuration, updateMask='isDefault').execute()

Il ne peut y avoir qu'une seule configuration par défaut. Le fait de définir une nouvelle configuration par défaut définit le champ isDefault d'une configuration précédente sur false. Vous devrez peut-être actualiser les instances Configuration mises en cache pour afficher les valeurs correctes dans les champs isDefault.

Guider les utilisateurs d'appareils

La configuration sans contact affiche des conseils personnalisés dans l'assistant de configuration de l'appareil pour aider les utilisateurs. Vous devez inclure dans une configuration un numéro de téléphone et une adresse e-mail de contact, ainsi que le nom de l'organisation qui gère l'appareil. Nous vous recommandons également d'inclure une ou deux phrases dans le champ customMessage pour donner plus d'informations sur ce qu'il advient de l'appareil d'un utilisateur.

Étant donné que l'utilisateur ne pourra pas appeler ni envoyer d'e-mail à partir de l'appareil qu'il configure, mettez en forme le numéro de téléphone et l'adresse e-mail pour pouvoir consulter plus facilement les informations.

Appareils

Les revendeurs créent des appareils lorsqu'un client les achète pour l'enregistrement sans contact. Les administrateurs informatiques ne peuvent pas créer d'appareils. Pour utiliser des appareils, appelez des méthodes sur la ressource d'API Device. Si vous devez rechercher des appareils, répertoriez-les tous et filtrez chaque lot localement dans votre application. Pour obtenir un exemple, consultez la section Résultats paginés ci-dessous.

Configurez des appareils

Lorsque vous appliquez une configuration à un appareil, celui-ci est enregistré pour l'enregistrement sans contact. Pour appliquer une configuration, appelez customers.devices.applyConfiguration. Après avoir appliqué une configuration, l'appareil se provisionne automatiquement au premier démarrage ou lors du prochain rétablissement de la configuration d'usine. L'exemple ci-dessous montre comment appliquer une configuration à un ensemble d'appareils:

Java

List<Device> devices = getDevicesToConfigure(service);
Configuration configurationToApply = getConfigurationToApply(service);

// Loop through the collection and apply the configuration to each device. This might
// take some time if the collection contains many devices.
for (Device device : devices) {
    System.out.println(device.getDeviceIdentifier().getImei());

    // Wrap the device ID in a DeviceReference.
    DeviceReference deviceRef = new DeviceReference();
    deviceRef.setDeviceId(device.getDeviceId());

    // Build and send the request to the API.
    CustomerApplyConfigurationRequest body = new CustomerApplyConfigurationRequest();
    body.setConfiguration(configurationToApply.getName());
    body.setDevice(deviceRef);

    AndroidProvisioningPartner.Customers.Devices.ApplyConfiguration request = service
          .customers()
          .devices()
          .applyConfiguration(customerAccount, body);
    request.execute();
}

.NET

IList<Device> devices = GetDevicesToConfigure(service);
Configuration configurationToApply = GetConfigurationToApply(service);

// Loop through the collection and apply the configuration to each device. This might
// take some time if the collection contains many devices.
foreach (Device device in devices)
{
    Console.WriteLine(device.DeviceIdentifier.Imei);

    // Wrap the device ID in a DeviceReference.
    var deviceRef = new DeviceReference
    {
        DeviceId = device.DeviceId
    };

    // Build and send the request to the API.
    CustomerApplyConfigurationRequest body = new CustomerApplyConfigurationRequest
    {
        Configuration = configurationToApply.Name,
        Device = deviceRef
    };
    var request = service.Customers.Devices.ApplyConfiguration(body,
                                                               customerAccount);
    request.Execute();
}

Python

devices = get_devices_to_configure(service)
configuration = get_configuration_to_apply(service)

# Loop through the collection and apply the configuration to each device.
# This might take some time if the collection contains many devices.
for device in devices:
  print(device['deviceIdentifier']['imei'])

  # Wrap the device ID in a DeviceReference.
  device_ref = {'deviceId': device['deviceId']}

  # Build and send the request to the API.
  body = {'configuration': configuration['name'], 'device': device_ref}
  service.customers().devices().applyConfiguration(
      parent=customer_account, body=body).execute()

Pour supprimer la configuration d'un appareil, appelez customers.devices.removeConfiguration. Cette modification prend effet après le rétablissement de la configuration d'usine de l'appareil.

Retirer la revendication d'appareils

Les administrateurs informatiques peuvent annuler la revendication d'un appareil pour le retirer de l'enregistrement sans contact. Un administrateur informatique peut retirer la revendication d'un appareil qu'il souhaite migrer vers un autre compte, vendre ou retourner au revendeur. Appelez la méthode customers.devices.unclaim pour retirer un appareil d'une organisation.

L'exemple ci-dessous montre comment retirer la revendication d'un appareil à partir d'un code IMEI et d'un nom de fabricant:

Java

// Wrap the hardware ID and manufacturer values in a DeviceIdentifier.
// Then wrap the DeviceIdentifier in a DeviceReference.
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setImei("123456789012347");
identifier.setManufacturer("Google");
DeviceReference reference = new DeviceReference();
reference.setDeviceIdentifier(identifier);

// Create the body of the request.
CustomerUnclaimDeviceRequest body = new CustomerUnclaimDeviceRequest();
body.setDevice(reference);

// Call the API method to unclaim the device from the organization.
service.customers().devices().unclaim(customerAccount, body).execute();

.NET

// Wrap the hardware ID and manufacturer values in a DeviceIdentifier.
// Then wrap the DeviceIdentifier in a DeviceReference.
DeviceIdentifier identifier = new DeviceIdentifier
{
    Imei = "123456789012347",
    Manufacturer = "Google"
};
DeviceReference reference = new DeviceReference();
reference.DeviceIdentifier = identifier;

// Create the body of the request.
CustomerUnclaimDeviceRequest body = new CustomerUnclaimDeviceRequest();
body.Device = reference;

// Call the API method to unclaim the device from the organization.
service.Customers.Devices.Unclaim(body, customerAccount).Execute();

Python

# Wrap the hardware ID and manufacturer values in a DeviceIdentifier.
# Then wrap the DeviceIdentifier in a DeviceReference.
identifier = {'imei': '123456789012347', 'manufacturer': 'Google'}
reference = {'deviceIdentifier': identifier}

# Create the body of the request.
body = {'device': reference}

# Call the API method to unclaim the device from the organization.
service.customers().devices().unclaim(
    parent=customer_account, body=body).execute()

Métadonnées de l'appareil

Un administrateur informatique peut voir les métadonnées associées à l'appareil par le revendeur. Affichez ces métadonnées d'appareil dans votre application pour aider les administrateurs informatiques à reconnaître les appareils.

Pour en savoir plus sur les métadonnées que vous pouvez voir, consultez le guide Métadonnées des appareils pour les revendeurs.

Résultats paginés

La méthode API customers.devices.list peut renvoyer de très longues listes d'appareils. Pour réduire la taille des réponses, cette méthode d'API et d'autres méthodes d'API (telles que customers.list) sont compatibles avec les résultats paginés. Avec les résultats paginés, votre application peut demander et traiter de grandes listes de manière itérative, page par page.

Après avoir appelé la méthode API, vérifiez si la réponse inclut une valeur pour nextPageToken. Si nextPageToken n'est pas null, votre application peut l'utiliser pour récupérer une autre page d'appareils en appelant à nouveau la méthode. Vous devez définir une limite supérieure pour le nombre d'appareils dans le paramètre pageSize. Si nextPageToken est défini sur null, votre application a demandé la dernière page.

L'exemple de méthode ci-dessous montre comment votre application peut imprimer une liste d'appareils, page par page:

Java

private void printDevices(AndroidProvisioningPartner service, String customerAccount,
      String pageToken) throws IOException {

    // Call the API to get a page of Devices. Send a page token from the method argument.
    // If the page token is null, the API returns the first page.
    AndroidProvisioningPartner.Customers.Devices.List request =
          service.customers().devices().list(customerAccount);
    request.setPageSize(50L);
    request.setPageToken(pageToken);
    CustomerListDevicesResponse response = request.execute();

    // Print the devices included in this page of results.
    for (Device device : response.getDevices()) {
        System.out.format("Device: %s\n", device.getName());
    }
    System.out.println("---");

    // Check to see if another page of devices is available. If yes, fetch & print the devices.
    if (response.getNextPageToken() != null) {
        this.printDevices(service, customerAccount, response.getNextPageToken());
    }
}

.NET

private void PrintDevices(AndroidProvisioningPartnerService service, String customerAccount,
                          String pageToken)
{
    // Call the API to get a page of Devices. Send a page token from the method argument.
    // If the page token is null, the API returns the first page.
    var request = service.Customers.Devices.List(customerAccount);
    request.PageSize = 50;
    request.PageToken = pageToken;
    var response = request.Execute();

    // Print the devices included in this page of results.
    foreach (Device device in response.Devices)
    {
        Console.WriteLine("Device: {0}", device.Name);
    }
    Console.WriteLine("---");

    // Check to see if another page of devices is available. If yes, fetch and print the devices.
    if (response.NextPageToken != null)
    {
        this.PrintDevices(service, customerAccount, response.NextPageToken);
    }
}

Python

def print_devices(service, customer_account, page_token):
  """Demonstrates how to loop through paginated lists of devices."""

  # Call the API to get a page of Devices. Send a page token from the method
  # argument. If the page token is None, the API returns the first page.
  response = service.customers().devices().list(
      parent=customer_account, pageSize=50, pageToken=page_token).execute()

  # Print the devices included in this page of results.
  for device in response['devices']:
    print('Device: {0}'.format(device['name']))
  print('---')

  # Check to see if another page of devices is available. If yes,
  # fetch and print the devices.
  if 'nextPageToken' in response:
    print_devices(service, customer_account, response['nextPageToken'])

Premiers pas

Ensuite, découvrez comment autoriser les appels d'API dans Autorisation. Si vous souhaitez explorer les API, consultez les guides de démarrage rapide pour Java, .NET et Python. Vous pouvez utiliser un colab pour afficher des exemples d'appels d'API et tester les appels d'API vous-même.