O SDK da API Android Management (AMAPI) permite que um app de extensão especificado pelo EMM
se comunique diretamente com o Android Device Policy (ADP) e execute Commands
no dispositivo.
Integração com o SDK AMAPI fornece mais informações sobre essa biblioteca e como adicioná-la ao seu aplicativo.
Depois de integrar o SDK, o app de extensão pode se comunicar com o ADP para:
- enviar solicitações de comando
- consultar o status das solicitações de comando
- receber mudanças de status de comando
Emitir comando
Um app de extensão pode solicitar que comandos sejam emitidos usando o ADP.
IssueCommandRequest
contém o objeto de solicitação que vai conter detalhes sobre o comando a ser emitido e parâmetros específicos.
O snippet a seguir mostra como emitir uma solicitação para limpar os dados do pacote:
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();
}
...
O exemplo anterior mostra como emitir uma solicitação de dados claros do app para pacotes
específicos e esperar até que o comando seja emitido. Se
emitido com sucesso, um objeto Command
será retornado com o status
atual do comando e o ID do comando, que pode ser usado mais tarde para consultar o status de
comandos de longa execução.
Comando "get"
Um app de extensão pode consultar o status de solicitações de comando emitidas anteriormente. Para
recuperar o status de um comando, você vai precisar do ID do comando (disponível na
solicitação de comando de emissão). O snippet a seguir mostra como enviar um
GetCommandRequest
para o 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());
}
...
Detectar callbacks de mudança de status do comando
Um app de extensão pode registrar um callback para receber atualizações de mudanças de status de comandos de execução longa seguindo estas etapas:
- As mudanças de status do comando são notificadas para
CommandListener
, implemente essa interface no seu app e forneça uma implementação sobre como processar as atualizações de status recebidas. - Estenda
NotificationReceiverService
e forneça uma instância deCommandListener
pelo métodogetCommandListener
. Especifique o nome da classe de
NotificationReceiverService
estendido na política da API Android Management (consulte a configuração de políticas).import com.google.android.managementapi.commands.CommandListener; import com.google.android.managementapi.notification.NotificationReceiverService; ... public class SampleCommandService extends NotificationReceiverService { @Override public CommandListener getCommandListener() { // return the concrete implementation from previous step return ...; } }
Configuração da política
Para permitir que o app de extensão se comunique diretamente com o ADP, o EMM precisa
fornecer uma 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"
}
}]
Teste
Teste de unidade
LocalCommandClient
é uma interface e, portanto, permite fornecer uma implementação
testável.
Teste de integração
As seguintes informações serão necessárias para testar com o ADP:
- Nome do pacote do app de extensão.
- O hash SHA-256 codificado em hexadecimal da assinatura associada ao pacote do app.
- Opcionalmente, se estiver testando o callback, o nome totalmente qualificado do serviço do
serviço recém-introduzido para oferecer suporte a callbacks. (Nome totalmente qualificado de
CommandService
no exemplo).