Cómo funciona

La API del cliente brinda control programático de dispositivos y configuración para la inscripción automática de Android. En este documento, se presenta la API para los proveedores de administración de movilidad empresarial (EMM) y los desarrolladores de TI empresariales. Después de leer este documento, debes comprender los recursos principales que se usan en la API y cómo interactúan. Si es la primera vez que usas la inscripción automática, lee la introducción breve de android.com.

Descripción general

La API del cliente ayuda a las organizaciones que compran dispositivos de inscripción automática de Android. Tu app o herramienta puede ayudar a los administradores de TI a realizar las siguientes acciones:

  • Crear, editar y borrar parámetros de configuración de aprovisionamiento
  • Aplica o quita una configuración en un dispositivo.
  • Selecciona una configuración predeterminada para los dispositivos que se agreguen a la inscripción automática de ahora en adelante.

A través de la API, los administradores de TI también pueden cancelar el registro de dispositivos de la inscripción automática. Para administrar los usuarios de su organización o aceptar las Condiciones del Servicio, los administradores de TI usan el portal de inscripción automática.

Los usuarios típicos de esta API pueden ser los siguientes:

  • Los proveedores de EMM agregan compatibilidad con la inscripción automática a sus consolas.
  • Desarrolladores de TI empresariales que crean herramientas para automatizar las tareas de inscripción automática

Recursos principales

Las configuraciones y los dispositivos son los recursos principales que usas en la API. Una organización también puede crear configuraciones y dispositivos mediante el portal de inscripción automática.

Relación entre el dispositivo y los recursos del cliente

Configuración
Los administradores de TI establecen opciones de aprovisionamiento para los dispositivos con una configuración. Las configuraciones incluyen políticas para dispositivos móviles de EMM y la información de contacto que se muestra para ayudar a los usuarios. Las configuraciones son fundamentales para la API, por lo que las usas en muchos métodos. Para obtener más información, consulta Configuraciones a continuación.
Dispositivo
Un dispositivo Android compatible con la inscripción automática que una organización compró a su revendedor. Aplica una configuración para incluir el dispositivo en la inscripción automática. Los dispositivos tienen ID de hardware y metadatos adjuntos. Para obtener más información, consulta la sección Dispositivos a continuación.
DPC
Es una referencia de solo lectura al DPC de un EMM (controlador de política de dispositivo). Agrega un DPC a una configuración para seleccionar la solución de EMM para los dispositivos. Todos los DPC enumerados por la API admiten la inscripción automática y están disponibles en Google Play. Para obtener más información, consulta Dpc.

Para enumerar todos los métodos y recursos de API que puede usar tu app, consulta la Referencia de la API.

Parámetros de configuración

El recurso de la API de Configuration combina lo siguiente:

  • El DPC de EMM instalado en los dispositivos.
  • Aplica políticas de EMM en los dispositivos.
  • Información de contacto que se muestra en el dispositivo para ayudar a los usuarios durante la configuración

Con la API, tu app puede administrar la configuración para administradores de TI. Llama a la API para recuperar, crear, actualizar y borrar configuraciones. En el siguiente ejemplo, se muestra cómo crear una configuración nueva:

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()

Cuando actualices una configuración con la API de parche, recuerda incluir la máscara de campo o un valor para cada campo que no desees que sea null. Consulta Configuraciones predeterminadas (a continuación) para ver un ejemplo que muestra cómo actualizar una configuración de manera eficiente.

Borrar parámetros de configuración

No puedes borrar una configuración si todavía se aplica a los dispositivos. Si intentas borrar una configuración en uso, el método de la API muestra un código de estado HTTP 400 Bad Request y un mensaje que explica cuántos dispositivos usan la configuración. Llama a customers.devices.removeConfiguration para quitar la configuración de los dispositivos antes de volver a intentarlo.

Configuración predeterminada.

La inscripción automática funciona mejor cuando una organización establece una configuración predeterminada que se aplica a cualquier dispositivo nuevo que compre. Considera pedirles a los administradores de TI que establezcan una configuración predeterminada si no se estableció una. En el siguiente ejemplo, se muestra cómo establecer una configuración existente como predeterminada estableciendo isDefault en 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()

Solo puede haber una configuración predeterminada. Cuando se realiza una nueva configuración predeterminada, se establece el campo isDefault de una configuración anterior en false. Es posible que debas actualizar las instancias de Configuration almacenadas en caché para ver los valores correctos en los campos isDefault.

Guía a los usuarios de dispositivos

La configuración de inscripción automática muestra instrucciones personalizadas para el usuario en el asistente de configuración del dispositivo a fin de ayudar a los usuarios. Debes incluir un número de teléfono y una dirección de correo electrónico de contacto junto con el nombre de la organización que administra el dispositivo en una configuración. También recomendamos incluir una o dos oraciones en el campo customMessage para brindar más detalles sobre lo que sucede con el dispositivo de un usuario.

Como el usuario no podrá llamar ni enviar correos electrónicos desde el dispositivo que está configurando, dale formato al número de teléfono y a la dirección de correo electrónico para que sea más fácil ver la información.

Dispositivos

Los revendedores crean dispositivos cuando un cliente los compra para la inscripción automática: los administradores de TI no pueden crear dispositivos. Para trabajar con dispositivos, llama a los métodos en el recurso de la API Device. Si necesitas buscar dispositivos, enumera todos los dispositivos y filtra cada lote de manera local en tu app. Para ver un ejemplo, consulta Resultados paginados a continuación.

Cómo configurar dispositivos

Cuando se aplica una configuración a un dispositivo, se registra el dispositivo para la inscripción automática. Para aplicar una configuración, llama a customers.devices.applyConfiguration. Después de aplicar una configuración, el dispositivo se aprovisiona automáticamente en el primer inicio o en el próximo restablecimiento de la configuración de fábrica. En el siguiente ejemplo, se muestra cómo puedes aplicar una configuración a una colección de dispositivos:

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()

Para quitar la configuración de un dispositivo, llama a customers.devices.removeConfiguration. El cambio se aplica después de restablecer la configuración de fábrica del dispositivo.

Rechazar dispositivos

Los administradores de TI pueden retirar un dispositivo para quitarlo de la inscripción automática. Un administrador de TI puede retirar un dispositivo que quiere migrar a otra cuenta, venderlo o devolverlo al revendedor. Llama al método customers.devices.unclaim para retirar un dispositivo de una organización.

En el siguiente ejemplo, se muestra cómo retirar un dispositivo de un número IMEI y nombre del fabricante:

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()

Metadatos del dispositivo

Un administrador de TI puede ver los metadatos que el revendedor adjuntó al dispositivo. Muestra los metadatos de este dispositivo en tu app para ayudar a los administradores de TI a reconocer los dispositivos.

Para obtener más información sobre los metadatos que puedes ver, consulta la guía Metadatos del dispositivo para revendedores.

Resultados paginados

Es posible que el método de API customers.devices.list muestre listas muy grandes de dispositivos. Para reducir el tamaño de la respuesta, este y otros métodos de la API (como customers.list) admiten resultados paginados. Con los resultados paginados, tu aplicación puede solicitar y procesar listas grandes de manera iterativa, una página a la vez.

Después de llamar al método de la API, verifica si la respuesta incluye un valor para nextPageToken. Si nextPageToken no es null, tu app puede usarlo para recuperar otra página de dispositivos llamando nuevamente al método. Debes establecer un límite superior para la cantidad de dispositivos en el parámetro pageSize. Si nextPageToken es null, tu app solicitó la última página.

En el método de ejemplo que aparece a continuación, se muestra cómo tu app podría imprimir una lista de dispositivos, una página a la vez:

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'])

Comenzar

A continuación, lee cómo autorizar llamadas a la API en Autorización. Si deseas explorar las APIs, consulta las guías de inicio rápido para Java, .NET y Python. Puedes usar un colab para ver ejemplos de llamadas a la API y experimentar con llamadas a la API por tu cuenta.