Apps de extensiones y comandos locales

El SDK de la API de Android Management (AMAPI) permite que una app de extensión especificada por EMM haga lo siguiente: comunicarse directamente con Android Device Policy (ADP) y ejecutar Commands en el dispositivo.

Integrar con el SDK de AMAPI proporciona más información sobre esta biblioteca y cómo agregarla a tu aplicación.

Una vez integrado el SDK, tu app de extensión puede comunicarse con ADP con lo siguiente:

Ejecutar comando

Una app de extensión puede solicitar que se emitan comandos con ADP. IssueCommandRequest contiene el objeto de solicitud que tendrá los detalles de el comando que se emitirá y los parámetros específicos.

En el siguiente fragmento, se muestra cómo emitir una solicitud para borrar los datos del paquete:

import android.util.Log;
...
import com.google.android.managementapi.commands.LocalCommandClientFactory;
import com.google.android.managementapi.commands.model.Command;
import com.google.android.managementapi.commands.model.GetCommandRequest;
import com.google.android.managementapi.commands.model.IssueCommandRequest;
import com.google.android.managementapi.commands.model.IssueCommandRequest.ClearAppsData;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;

...
  void issueClearAppDataCommand(ImmutableList<String> packageNames) {
    Futures.addCallback(
        LocalCommandClientFactory.create(getContext())
            .issueCommand(createClearAppRequest(packageNames)),
        new FutureCallback<Command>() {
          @Override
          public void onSuccess(Command result) {
            // Process the returned command result here
            Log.i(TAG, "Successfully issued command");
          }

          @Override
          public void onFailure(Throwable t) {
            Log.e(TAG, "Failed to issue command", t);
          }
        },
        MoreExecutors.directExecutor());
  }

  IssueCommandRequest createClearAppRequest(ImmutableList<String> packageNames) {
    return IssueCommandRequest.builder()
        .setClearAppsData(
            ClearAppsData.builder()
                .setPackageNames(packageNames)
                .build()
        )
        .build();
  }
...

En el ejemplo anterior, se muestra la emisión de una solicitud clara de datos de la app para paquetes y hasta que el comando se haya emitido correctamente. Si se emite correctamente, se devolverá un objeto Command con el valor estado del comando y el ID del comando, que puede usarse más adelante para consultar el estado de cualquier comando de larga duración.

Obtener comando

Una app de extensión puede consultar el estado de solicitudes de comando emitidas anteriormente. Para para recuperar el estado de un comando, necesitarás el ID del comando (disponible en emitir una solicitud de comando). En el siguiente fragmento, se muestra cómo enviar un GetCommandRequest a ADP

import android.util.Log;
...
import com.google.android.managementapi.commands.LocalCommandClientFactory;
...
import com.google.android.managementapi.commands.model.GetCommandRequest;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;

...
  void getCommand(String commandId) {
    Futures.addCallback(
        LocalCommandClientFactory.create(getApplication())
            .getCommand(GetCommandRequest.builder().setCommandId(commandId).build()),
        new FutureCallback<Command>() {
          @Override
          public void onSuccess(Command result) {
            // Process the returned command result here
            Log.i(Constants.TAG, "Successfully issued command");
          }

          @Override
          public void onFailure(Throwable t) {
            Log.e(Constants.TAG, "Failed to issue command", t);
          }
        },
        MoreExecutors.directExecutor());
  }
  ...

Escucha las devoluciones de llamada de cambio de estado de los comandos

Una app de extensión puede registrar una devolución de llamada para recibir actualizaciones sobre los cambios de estado de comandos de larga duración mediante estos pasos:

  1. Los cambios en el estado del comando se notifican a CommandListener; implementa lo siguiente de la app y ofrece una implementación sobre cómo manejar el actualizaciones de estado recibidas.
  2. Extiende NotificationReceiverService y proporciona CommandListener instancia.
  3. Especifica el nombre de clase del NotificationReceiverService extendido en Android Management de la API (consulta Configuración de políticas).

    import com.google.android.managementapi.commands.CommandListener;
    import com.google.android.managementapi.notification.NotificationReceiverService;
    
    ...
    
    public class SampleCommandService extends NotificationReceiverService {
    
      @Override
      protected void setupInjection() {
        // (Optional) If using DI and needs initialisation then use this method.
      }
    
      @Override
      public CommandListener getCommandListener() {
        // return the concrete implementation from previous step
        return ...;
      }
    }
    
  4. Agrega el servicio a tu AndroidManifest.xml y asegúrate de que se exporte.

    <service
     android:name = ".notification.SampleCommandService"
     android:exported = "true" />
    

Configuración de políticas

Para permitir que la app de extensión se comunique directamente con ADP, la EMM debe Proporcionar una política extensionConfig

 "applications": [{
   "packageName": "com.amapi.extensibility.demo",
   ...
   "extensionConfig": {
     "signingKeyFingerprintsSha256": [
       // Include signing key of extension app
     ],
     // Optional if callback is implemented
     "notificationReceiver": "com.amapi.extensibility.demo.notification.SampleCommandService"
   }
 }]

Prueba

Pruebas de unidades

LocalCommandClient es una interfaz y, por lo tanto, permite proporcionar un elemento para implementarlos.

Pruebas de integración

Se necesitará la siguiente información para realizar pruebas con ADP:

  1. Nombre del paquete de la extensión de la app.
  2. El hash SHA-256 con codificación hexadecimal de la firma asociada con la app .
  3. Opcionalmente, si se está probando la devolución de llamada, el nombre completamente calificado del servicio de el servicio recientemente presentado para admitir la devolución de llamada. (Nombre completamente calificado de CommandService en el ejemplo).