Tích hợp với SDK AMAPI

SDK AMAPI cho phép ứng dụng tiện ích được EMM chỉ định giao tiếp trực tiếp với Android Device Policy. Hiện tại, thư viện này hỗ trợ việc thực thi cục bộ Commands và chỉ hỗ trợ lệnh ClearAppData. Bạn phải thực hiện các bước sau đây để tích hợp với SDK:

  1. Thêm thư viện vào ứng dụng tiện ích.
  2. Sử dụng các API được cung cấp để đưa ra lệnh theo yêu cầu.
  3. Thêm phần tử truy vấn nếu SDK mục tiêu >= 30.
  4. Bạn có thể tuỳ ý cung cấp cách triển khai dịch vụ để theo dõi lệnh gọi lại thay đổi trạng thái lệnh.
  5. Cấp phép cho thiết bị có chính sách về khả năng mở rộng.

Điều kiện tiên quyết

  • Đảm bảo minSdkVersion của ứng dụng tiện ích được đặt thành API tối thiểu là 21.

Thêm thư viện vào ứng dụng tiện ích

Trong tệp build.gradle cấp cao nhất, hãy thêm kho lưu trữ Google Maven chứa thư viện SDK vào các mô-đun có liên quan và thêm phần phụ thuộc vào thư viện:

repositories {
  ...
  google()
}

Sau đó, hãy thêm thư viện vào khối phần phụ thuộc của mô-đun:

dependencies {
  implementation 'com.google.android.libraries.enterprise.amapi:amapi:1.0.0'
}

Gửi yêu cầu tới Android Device Policy

Hiện bạn có thể gửi yêu cầu tới ADP. Các yêu cầu sau đây được hỗ trợ.

Lệnh phát hành

Ứng dụng tiện ích có thể yêu cầu thực hiện các lệnh bằng ADP. IssueCommandRequest chứa đối tượng yêu cầu sẽ chứa thông tin chi tiết về lệnh cần được phát hành và các tham số cụ thể. Bạn có thể xem thêm thông tin về vấn đề này trong Javadoc.

Đoạn mã sau đây cho biết cách đưa ra yêu cầu xoá dữ liệu của gói:

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

Ví dụ trên cho thấy việc tạo một yêu cầu dữ liệu ứng dụng rõ ràng cho các gói đã chỉ định và chờ cho đến khi lệnh được đưa ra thành công. Nếu phát hành thành công, đối tượng Command sẽ được trả về cùng với trạng thái lệnh hiện tại và mã nhận dạng lệnh mà sau đó có thể được dùng để truy vấn trạng thái của bất kỳ lệnh nào chạy trong thời gian dài.

Nhận lệnh

Ứng dụng tiện ích cũng có thể truy vấn trạng thái của các yêu cầu lệnh đã đưa ra trước đó. Để truy xuất trạng thái của một lệnh, bạn cần có mã lệnh (có trong yêu cầu lệnh phát hành). Đoạn mã sau đây cho thấy việc gửi yêu cầu GetCommand tới 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());
  }
  ...

Thêm phần tử truy vấn

Nếu ứng dụng của bạn nhắm mục tiêu đến SDK 30 trở lên, thì bạn cần có phần tử truy vấn trong tệp kê khai để chỉ định rằng phần tử đó sẽ tương tác với ADP.

<queries>
    <package android:name="com.google.android.apps.work.clouddpc" />
</queries>

Xem bài viết Lọc phạm vi xem gói trên Android để biết thêm thông tin.

Nghe lệnh gọi lại thay đổi trạng thái lệnh

  1. Các thay đổi về trạng thái lệnh sẽ được thông báo cho CommandListener, hãy triển khai giao diện này trong ứng dụng và đưa ra cách xử lý các thông tin cập nhật trạng thái nhận được.
  2. Mở rộng NotificationReceiverService và cung cấp thực thể CommandListener.
  3. Chỉ định tên lớp của NotificationReceiverService mở rộng trong chính sách API Quản lý Android (xem Cấu hình chính sách).

    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. Thêm dịch vụ vào AndroidManifest.xml của bạn và đảm bảo rằng bạn đã xuất dịch vụ đó.

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

Cấu hình chính sách

 "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"
   }
 }]

Kiểm thử

Kiểm thử đơn vị

LocalCommandClient là một giao diện, do đó, quy trình kiểm thử cho phép dễ dàng cung cấp phương thức triển khai có thể kiểm thử.

Kiểm thử tích hợp

Cần có thông tin sau để kiểm thử với Android Device Policy:

  1. Tên gói của ứng dụng tiện ích.
  2. Hàm băm SHA-256 được mã hoá hex của Chữ ký được liên kết với gói ứng dụng.
  3. Nếu muốn kiểm thử lệnh gọi lại – tên đủ điều kiện của dịch vụ từ dịch vụ mới được giới thiệu để hỗ trợ lệnh gọi lại (không bắt buộc). (Trong ví dụ này, tên đủ điều kiện hoàn toàn của CommandService).