O SDK da API Android Management (AMAPI, na sigla em inglês) permite que um app de extensão especificado pelo EMM se
comunique diretamente com o Android Device Policy (ADP) e execute Commands
no dispositivo.
Integrar com o SDK da AMAPI oferece mais informações sobre essa biblioteca e como adicioná-la ao seu aplicativo.
Depois de integrar o SDK, o app de extensão poderá se comunicar com o ADP para:
- enviar solicitações de comando
- consultar o status das solicitações de comando
- receber mudanças no status do comando
Emitir comando
Um app de extensão pode solicitar que os comandos sejam emitidos usando o ADP.
IssueCommandRequest contém o objeto de solicitação que terá detalhes sobre o comando a ser emitido e parâmetros específicos.
O snippet a seguir mostra como enviar 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 a emissão de uma solicitação de dados de app limpos para pacotes especificados e a espera 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 duração.
Receber comando
Um app de extensão pode consultar o status das solicitações de comando emitidas anteriormente. Para recuperar o status de um comando, você 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 de comando
Um app de extensão pode registrar um callback para receber atualizações de mudanças de status de comandos de longa duração seguindo estas etapas:
- As mudanças de status do comando são notificadas ao
CommandListener. Implemente esta interface no seu app e forneça a implementação de como processar as atualizações de status recebidas. - Estenda
NotificationReceiverServicee forneça uma instânciaCommandListenerpelo métodogetCommandListener. Configure a política do aplicativo para atribuir o papel
COMPANION_APPao seu app (consulte Configuração da política).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 atribuir o papel COMPANION_APP ao app usando o campo roles na política do aplicativo.
"applications": [{
"packageName": "com.amapi.extensibility.demo",
"installType": "FORCE_INSTALLED",
"roles": [
{ "roleType": "COMPANION_APP" }
]
}]
Para mais opções disponíveis, consulte Provisionar o dispositivo com políticas de papéis de app.
Teste
Teste de unidade
LocalCommandClient é uma interface e, portanto, permite fornecer uma implementação testável.
Teste de integração
As informações a seguir serão necessárias para testar com o ADP:
- Nome do pacote do app de extensão.
- O hash SHA-256 codificado em Base64 da assinatura associada ao pacote do app.
- Opcionalmente, se você estiver testando o callback, o nome totalmente qualificado do serviço do serviço recém-introduzido para oferecer suporte ao callback. (Nome totalmente qualificado de
CommandServiceno exemplo).