Приложения расширения и локальные команды

SDK Android Management API (AMAPI) позволяет приложению-расширению, указанному в EMM, напрямую взаимодействовать с политикой устройств Android (ADP) и выполнять Commands на устройстве.

В разделе «Интеграция с AMAPI SDK» представлена ​​дополнительная информация об этой библиотеке и о том, как добавить ее в ваше приложение.

После интеграции SDK ваше приложение-расширение сможет взаимодействовать с ADP следующим образом:

Выдать команду

Расширение приложения может запрашивать выполнение команд с помощью ADP. Объект IssueCommandRequest содержит запрос, в котором будут указаны подробные сведения о выполняемой команде и конкретные параметры.

Следующий фрагмент кода показывает, как отправить запрос на очистку данных пакета:

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();
  }
...

В предыдущем примере показано, как отправляется запрос на очистку данных приложения для указанных пакетов и ожидается, пока команда не будет успешно выполнена. В случае успешного выполнения возвращается объект Command с текущим статусом команды и идентификатором команды, который впоследствии можно использовать для запроса статуса любых длительно выполняющихся команд.

Получить команду

Расширение приложения может запрашивать статус ранее отправленных запросов команд. Для получения статуса команды вам потребуется идентификатор команды (доступен из запроса на отправку команды). Следующий фрагмент кода показывает, как отправить запрос GetCommandRequest в 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());
  }
  ...

Прослушивание обратных вызовов при изменении статуса команды

Дополнительное приложение может зарегистрировать функцию обратного вызова для получения обновлений об изменениях статуса длительно выполняющихся команд, выполнив следующие шаги:

  1. Изменения статуса команды передаются в CommandListener ; реализуйте этот интерфейс в своем приложении и предоставьте описание обработки полученных обновлений статуса.
  2. Расширьте класс NotificationReceiverService и предоставьте экземпляр CommandListener через метод getCommandListener .
  3. Настройте политику приложения, чтобы назначить вашему приложению роль COMPANION_APP (см. раздел «Настройка политики» ).

    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 ...;
     }
    }
    

Настройка политики

Для обеспечения прямой связи приложения-расширения с ADP, EMM должен назначить приложению роль COMPANION_APP , используя поле roles в политике приложения.

 "applications": [{
   "packageName": "com.amapi.extensibility.demo",
   "installType": "FORCE_INSTALLED",
   "roles": [
     { "roleType": "COMPANION_APP" }
   ]
 }]

Дополнительные параметры см. в разделе «Настройка политики ролей приложений на устройстве» .

Тестирование

модульное тестирование

LocalCommandClient — это интерфейс, позволяющий предоставить тестируемую реализацию.

Интеграционное тестирование

Для тестирования с помощью ADP потребуется следующая информация:

  1. Название пакета приложения-расширения.
  2. Хэш SHA-256 подписи, связанной с пакетом приложения, закодированный в base64.
  3. При необходимости, если тестируется функция обратного вызова, можно указать полное имя службы из вновь созданной службы, поддерживающей обратный вызов. (В примере это полное имя CommandService ).