El SDK de la API de administración de Android (AMAPI) permite que una app de extensión especificada por EMM se comunique directamente con Android Device Policy (ADP) y ejecute Commands
en el dispositivo.
En Integrar con el SDK de AMAPI, se 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:
- enviar solicitudes de comandos
- consultar el estado de las solicitudes de comando
- recibir cambios de estado de comandos
Ejecutar comando
Una app de extensión puede solicitar que se emitan comandos con ADP.
IssueCommandRequest
contiene el objeto de solicitud que incluirá detalles sobre 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 cómo emitir una solicitud clara de datos de la app para paquetes
especificados y esperar a que el comando se emita de forma correcta. Si se emite correctamente, se mostrará un objeto Command
con el estado actual del comando y el ID del comando, que se puede usar 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 recuperar el estado de un comando, necesitarás el ID del comando (disponible en la solicitud de comando de emisión). 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 de los cambios de estado de los comandos de larga duración mediante estos pasos:
- Los cambios en el estado del comando se notifican a
CommandListener
. Implementa esta interfaz en tu app y proporciona una implementación sobre cómo controlar las actualizaciones de estado recibidas. - Extiende
NotificationReceiverService
y proporciona la instancia deCommandListener
. Especifica el nombre de clase de la
NotificationReceiverService
extendida en la política de la API de administración de Android (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 ...; } }
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 una implementación que se puede probar.
Pruebas de integración
Se necesitará la siguiente información para realizar pruebas con ADP:
- Nombre del paquete de la extensión de la app.
- El hash SHA-256 con codificación hexadecimal de la firma asociada con el paquete de la app.
- De manera opcional, si se prueba la devolución de llamada: Es el nombre completamente calificado del servicio del servicio recién introducido para admitir la devolución de llamada. (Nombre completamente calificado de
CommandService
en el ejemplo).