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

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 객체가 반환됩니다.

Get 명령어

확장 프로그램 앱은 이전에 실행된 명령어 요청의 상태를 쿼리할 수 있습니다. 명령어의 상태를 검색하려면 명령어 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를 확장하고 getCommandListener 메서드를 통해 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
     public CommandListener getCommandListener() {
       // return the concrete implementation from previous step
       return ...;
     }
    }
    

정책 구성

확장 프로그램 앱이 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의 정규화된 이름)