אפליקציות של תוספים ופקודות מקומיות

ה-SDK של Android Management API (AMAPI) מאפשר לאפליקציית תוסף שצוין ב-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();
  }
...

הדוגמה הקודמת ממחישה איך שולחים בקשה ברורה לנתוני אפליקציה לחבילות ספציפיות ומחכים עד שהפקודה תונפק בהצלחה. אם היא תונפק בהצלחה, אובייקט Command יוחזר עם הסטטוס הנוכחי של הפקודה ומזהה הפקודה, שיכול לשמש מאוחר יותר כדי לשלוח שאילתות על הסטטוס של פקודות שפועלות לאורך זמן.

קבלת פקודה

אפליקציית תוספים יכולה לשלוח שאילתות לגבי הסטטוס של בקשות לפקודות שהונפקו בעבר. כדי לאחזר את הסטטוס של פקודה, יש צורך במזהה הפקודה (שמופיע בבקשה לפקודת הבעיה). קטע הקוד הבא מראה איך לשלוח GetCommandRequest ל-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());
  }
  ...

האזנה לקריאה חוזרת (callback) של שינוי סטטוס הפקודה

אפליקציית תוספים יכולה לרשום קריאה חוזרת כדי לקבל עדכונים לגבי שינויי סטטוס של פקודות שפועלות לאורך זמן:

  1. שינויים בסטטוס הפקודות מקבלים הודעה ל-CommandListener, מטמיעים את הממשק הזה באפליקציה ומספקים הטמעה של אופן הטיפול בעדכוני הסטטוס שהתקבלו.
  2. מרחיבים את NotificationReceiverService ומספקים מכונה של CommandListener.
  3. מציינים את שם המחלקה המורחבת של NotificationReceiverService במדיניות ה-Management API של Android (מידע נוסף על הגדרת המדיניות).

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

בדיקה

בדיקות יחידה (unit testing)

LocalCommandClient הוא ממשק שמאפשר לספק הטמעה שניתן לבדוק.

בדיקת אינטגרציה

כדי לבצע בדיקה באמצעות ADP תצטרכו את הפרטים הבאים:

  1. שם החבילה של אפליקציית התוסף.
  2. גיבוב SHA-256 עם קידוד הקסדצימלי של החתימה המשויכת לחבילת האפליקציה.
  3. אופציונלי: אם רוצים לבדוק קריאה חוזרת (callback) – השם המלא של השירות מהשירות החדש שנוסף כדי לתמוך בקריאה חוזרת (callback). (שם מלא של CommandService בדוגמה).