Aplikacje rozszerzeń i polecenia lokalne

Pakiet SDK interfejsu Android Management API (AMAPI) umożliwia aplikacji rozszerzenia wskazanego przez EMM bezpośrednie komunikowanie się z Android Device Policy (ADP) i uruchamianie Commands na urządzeniu.

Artykuł Integracja z pakietem SDK AMAPI zawiera więcej informacji o tej bibliotece i sposobie dodawania jej do aplikacji.

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

Wydaj polecenie

Aplikacja rozszerzenia może prosić o polecenia wydawane przez ADP. IssueCommandRequest zawiera obiekt żądania, który zawiera szczegółowe informacje o poleceniu, które zostanie wykonane, oraz konkretne parametry.

Z tego fragmentu dowiesz się, jak wysłać żądanie usunięcia 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();
  }
...

Wcześniejszy przykład pokazuje wysłanie żądania czyszczenia danych aplikacji w przypadku określonych pakietów i oczekiwanie na pomyślne wykonanie polecenia. Jeśli operacja się uda, obiekt Command zostanie zwrócony z bieżącym stanem polecenia i identyfikatorem polecenia, którego można później używać do sprawdzania stanu dowolnych długo trwających poleceń.

Pobierz polecenie

Aplikacja rozszerzenia może sprawdzać stan wcześniej wydanych żądań poleceń. Aby sprawdzić stan polecenia, potrzebujesz identyfikatora polecenia (dostępnego z poziomu żądania polecenia dotyczącego problemu). Z tego fragmentu kodu dowiesz się, 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());
  }
  ...

Wykrywaj wywołania zwrotne zmiany stanu polecenia

Aplikacja z rozszerzeniem może zarejestrować wywołanie zwrotne w celu otrzymywania aktualizacji stanu długotrwałych poleceń. Aby to zrobić:

  1. O zmianach stanu polecenia są powiadamiane do CommandListener, implementujesz ten interfejs w swojej aplikacji i umieszczasz informacje o sposobie obsługi otrzymanych aktualizacji stanu.
  2. Rozszerz zakres NotificationReceiverService i podaj instancję CommandListener.
  3. Określ nazwę klasy rozszerzonej NotificationReceiverService w zasadach interfejsu Android Management API (zobacz Konfiguracja zasad).

    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 ...;
      }
    }
    
  4. Dodaj usługę do: AndroidManifest.xml i upewnij się, że została wyeksportowana.

    <service
     android:name = ".notification.SampleCommandService"
     android:exported = "true" />
    

Konfiguracja zasady

Aby umożliwić aplikacji rozszerzenia bezpośrednią komunikację z ADP, dostawca usług EMM musi udostępnić zasadę 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"
   }
 }]

Testuję

Testowanie jednostkowe

LocalCommandClient to interfejs, który pozwala udostępnić możliwą do przetestowania implementację.

Testowanie integracji

Aby przeprowadzić test za pomocą ADP, potrzebne będą te informacje:

  1. Nazwa pakietu aplikacji rozszerzenia.
  2. Zakodowany szesnastkowo identyfikator SHA-256 podpisu powiązanego z pakietem aplikacji.
  3. Opcjonalnie w przypadku testowania wywołania zwrotnego – w pełni kwalifikowana nazwa usługi z nowo wprowadzonej usługi obsługującej wywołania zwrotne. (W pełni kwalifikowana nazwa elementu CommandService w przykładzie).