Aplikacje rozszerzeń i polecenia lokalne

Pakiet SDK interfejsu Android Management API (AMAPI) umożliwia określonej przez EMM aplikacji rozszerzającej bezpośrednią komunikację z aplikacją Android Device Policy (ADP) i wykonywanie na urządzeniu Commands.

Więcej informacji o tej bibliotece i o tym, jak dodać ją do aplikacji, znajdziesz w artykule Integracja z pakietem SDK AMAPI.

Po zintegrowaniu pakietu SDK aplikacja rozszerzenia może komunikować się z ADP w celu:

Wydawanie poleceń

Aplikacja rozszerzenia może żądać wydawania poleceń za pomocą ADP. IssueCommandRequest zawiera obiekt żądania, który będzie zawierać szczegółowe informacje o poleceniu do wydania i konkretnych parametrach.

Poniższy fragment kodu pokazuje, jak wysłać żądanie wyczyszczenia danych pakietu:

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

W poprzednim przykładzie pokazano wysyłanie żądania wyczyszczenia danych aplikacji dla określonych pakietów i oczekiwanie na pomyślne wykonanie polecenia. Jeśli polecenie zostanie wydane prawidłowo, zwrócony zostanie obiekt Command z bieżącym stanem polecenia i identyfikatorem polecenia, którego można później użyć do sprawdzenia stanu długotrwałych poleceń.

Pobierz polecenie

Aplikacja rozszerzająca może wysyłać zapytania o stan wcześniej wydanych żądań poleceń. Aby pobrać stan polecenia, musisz mieć jego identyfikator (dostępny w żądaniu wydania polecenia). Poniższy fragment kodu pokazuje, jak wysłać GetCommandRequest do 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());
  }
  ...

Nasłuchiwanie wywołań zwrotnych zmiany stanu polecenia

Aplikacja rozszerzająca może opcjonalnie zarejestrować wywołanie zwrotne, aby otrzymywać aktualizacje dotyczące zmian stanu długotrwałych poleceń, wykonując te czynności:

  1. Zmiany stanu polecenia są zgłaszane do CommandListener. Zaimplementuj ten interfejs w aplikacji i podaj sposób obsługi otrzymywanych aktualizacji stanu.
  2. Rozszerz NotificationReceiverService i podaj instancję CommandListener za pomocą metody getCommandListener.
  3. Skonfiguruj zasady aplikacji, aby przypisać do niej rolę COMPANION_APP (patrz Konfiguracja zasad).

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

Konfiguracja zasad

Aby umożliwić aplikacji rozszerzającej bezpośrednią komunikację z ADP, platforma EMM musi przypisać aplikacji rolę COMPANION_APP za pomocą pola roles w zasadach aplikacji.

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

Więcej dostępnych opcji znajdziesz w artykule Provision the device with app roles policies (w języku angielskim).

Testowanie

Testy jednostkowe

LocalCommandClient jest interfejsem, a więc umożliwia dostarczenie implementacji, którą można przetestować.

Testy integracji

Aby przeprowadzić test z ADP, musisz podać te informacje:

  1. Nazwa pakietu aplikacji rozszerzenia.
  2. Identyfikator SHA-256 podpisu powiązanego z pakietem aplikacji zakodowany w base64.
  3. Opcjonalnie, jeśli testujesz wywołanie zwrotne – pełna nazwa usługi z nowo wprowadzonej usługi obsługującej wywołanie zwrotne. (Pełna i jednoznaczna nazwa CommandService w przykładzie).