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:
- 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 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:
- 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. - Extiende
NotificationReceiverService
y proporcionaCommandListener
instancia. 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 ...; } }
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:
- Nombre del paquete de la extensión de la app.
- El hash SHA-256 con codificación hexadecimal de la firma asociada con la app .
- 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).