확장 프로그램 앱 및 로컬 명령어

Android Management API (AMAPI) SDK를 사용하면 EMM 지정 확장 프로그램 앱이 Android Device Policy (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();
  }
...

이전 예에서는 지정된 패키지에 관해 명확한 앱 데이터 요청을 실행하고 명령어가 성공적으로 실행될 때까지 기다리는 방법을 보여줍니다. 성공적으로 실행되면 현재 명령어 상태 및 나중에 장기 실행 명령어의 상태를 쿼리하는 데 사용할 수 있는 명령어 ID가 포함된 Command 객체가 반환됩니다.

명령어 가져오기

확장 프로그램 앱은 이전에 실행된 명령 요청의 상태를 쿼리할 수 있습니다. 명령어 상태를 검색하려면 명령어 ID (명령어 실행 요청에서 확인 가능)가 필요합니다. 다음 스니펫은 ADP에 GetCommandRequest를 전송하는 방법을 보여줍니다.

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 인스턴스를 제공합니다.
  3. Android Management API 정책에 확장된 NotificationReceiverService의 클래스 이름을 지정합니다 (정책 구성 참고).

    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. 서비스를 AndroidManifest.xml에 추가하고 서비스가 내보내졌는지 확인합니다.

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

정책 구성

확장 프로그램 앱이 ADP와 직접 통신할 수 있도록 하려면 EMM은 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"
   }
 }]

테스트

단위 테스트

LocalCommandClient는 인터페이스이므로 테스트 가능한 구현을 제공할 수 있습니다.

통합 테스트

ADP로 테스트하려면 다음 정보가 필요합니다.

  1. 확장 프로그램 앱의 패키지 이름입니다.
  2. 앱 패키지와 연결된 서명의 16진수로 인코딩된 SHA-256 해시입니다.
  3. 콜백을 테스트하는 경우 선택적으로, 콜백을 지원하기 위해 새로 도입된 서비스의 정규화된 서비스 이름입니다. (예시에서 CommandService의 정규화된 이름).