एक्सटेंशन ऐप्लिकेशन और लोकल निर्देश

Android Management API (AMAPI) SDK की मदद से, ईएमएम के तय किए गए एक्सटेंशन ऐप्लिकेशन को Android Device Policy (ADP) के साथ सीधे तौर पर कम्यूनिकेट करने और डिवाइस पर Commands को लागू करने की सुविधा मिलती है.

एएमएपीआई एसडीके के साथ इंटिग्रेट करें पेज पर, इस लाइब्रेरी के बारे में ज़्यादा जानकारी दी गई है. साथ ही, इसे अपने ऐप्लिकेशन में जोड़ने का तरीका भी बताया गया है.

एसडीके टूल को इंटिग्रेट करने के बाद, आपका एक्सटेंशन ऐप्लिकेशन, एडीपी के साथ कम्यूनिकेट कर सकता है. इससे ये काम किए जा सकते हैं:

निर्देश दें

कोई एक्सटेंशन ऐप्लिकेशन, एडीपी का इस्तेमाल करके निर्देश जारी करने का अनुरोध कर सकता है. 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 ऑब्जेक्ट दिखेगा. इसका इस्तेमाल, बाद में लंबे समय से चल रहे किसी भी कमांड की स्थिति के बारे में क्वेरी करने के लिए किया जा सकता है.

डिवाइस या वर्क प्रोफ़ाइल को वाइप करना

जब आईटी एडमिन, LOCAL_DEVICE_WIPE_COMMAND_ALLOWED की अतिरिक्त सुविधा के साथ COMPANION_APP की भूमिका असाइन करता है, तब कंपैनियन ऐप्लिकेशन, लोकल Wipe कमांड जारी कर सकता है. कंपनी के मालिकाना हक वाले डिवाइसों पर, यह डिवाइस को फ़ैक्ट्री रीसेट कर देता है. वहीं, वर्क प्रोफ़ाइल वाले निजी डिवाइसों पर, यह वर्क प्रोफ़ाइल को हटा देता है. अगर ऐप्लिकेशन के पास यह भूमिका और अतिरिक्त सुविधा नहीं है, तो अनुरोध पूरा नहीं हो पाता. ज़्यादा जानकारी के लिए, नीति कॉन्फ़िगरेशन देखें.

दोनों Wipe पैरामीटर ज़रूरी नहीं हैं. अगर आपको कोई वैल्यू नहीं देनी है, तो बिल्डर सेटर को छोड़ दें या खाली कलेक्शन या खाली स्ट्रिंग पास करें. null पास न करें.

  • WipeDataFlag वैल्यू से यह कंट्रोल किया जाता है कि कौनसा डेटा मिटाया जाए:
    • PRESERVE_RESET_PROTECTION_DATA: फ़ैक्ट्री रीसेट करने से जुड़ी सुरक्षा का डेटा सेव रखता है. डिफ़ॉल्ट रूप से, यह डेटा मिट जाता है. यह सिर्फ़ कंपनी के मालिकाना हक वाले डिवाइसों पर लागू होता है.
    • WIPE_EXTERNAL_STORAGE: इससे एसडी कार्ड जैसे बाहरी स्टोरेज का डेटा भी मिट जाता है. यह सिर्फ़ कंपनी के मालिकाना हक वाले डिवाइसों पर लागू होता है.
    • WIPE_ESIMS: कंपनी के मालिकाना हक वाले डिवाइसों से सभी ई-सिम हटाता है. निजी डिवाइसों पर, सिर्फ़ मैनेज किए जा रहे ई-सिम हटाए जाते हैं. Android 16 या इसके बाद के वर्शन पर, मैनेज किए जा रहे ई-सिम हमेशा वर्क प्रोफ़ाइल के साथ हटा दिए जाते हैं. भले ही, यह फ़्लैग सेट हो या नहीं.
  • wipeReason: ज़्यादा से ज़्यादा 200 वर्णों का एक छोटा मैसेज, जो उपयोगकर्ता को तब दिखता है, जब उसके निजी डिवाइस से वर्क प्रोफ़ाइल को हटाया जाता है. इसका असर, कंपनी के मालिकाना हक वाले डिवाइसों पर नहीं पड़ता.

यहां दिए गए स्निपेट में, डिवाइस या वर्क प्रोफ़ाइल को वाइप करने का अनुरोध करने का तरीका बताया गया है:

Kotlin

import android.content.Context
import android.util.Log
...
import com.google.android.managementapi.commands.CommandException
import com.google.android.managementapi.commands.LocalCommandClientFactory
import com.google.android.managementapi.commands.model.IssueCommandRequest
import com.google.android.managementapi.commands.model.IssueCommandRequest.Wipe
import com.google.android.managementapi.commands.model.IssueCommandRequest.Wipe.WipeDataFlag

...
  suspend fun issueWipeCommand(
      context: Context,
      wipeDataFlags: List<WipeDataFlag>,
      wipeReason: String,
  ) {
    try {
      val command =
          LocalCommandClientFactory.create(context)
              .issueCommandAwait(createWipeRequest(wipeDataFlags, wipeReason))
      Log.i(TAG, "Successfully issued wipe command: ${command.commandId}")
    } catch (e: CommandException) {
      Log.e(TAG, "Failed to issue wipe command", e)
    }
  }

  fun createWipeRequest(
      wipeDataFlags: List<WipeDataFlag>,
      wipeReason: String,
  ): IssueCommandRequest =
      IssueCommandRequest.builder()
          .setWipe(
              Wipe.builder()
                  .setWipeDataFlags(wipeDataFlags)
                  .setWipeReason(wipeReason)
                  .build()
          )
          .build()
...

Java

import android.content.Context;
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.IssueCommandRequest;
import com.google.android.managementapi.commands.model.IssueCommandRequest.Wipe;
import com.google.android.managementapi.commands.model.IssueCommandRequest.Wipe.WipeDataFlag;
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 issueWipeCommand(
      Context context,
      ImmutableList<WipeDataFlag> wipeDataFlags,
      String wipeReason) {
    Futures.addCallback(
        LocalCommandClientFactory.create(context)
            .issueCommand(createWipeRequest(wipeDataFlags, wipeReason)),
        new FutureCallback<Command>() {
          @Override
          public void onSuccess(Command result) {
            Log.i(TAG, "Successfully issued wipe command: " + result.getCommandId());
          }

          @Override
          public void onFailure(Throwable t) {
            Log.e(TAG, "Failed to issue wipe command", t);
          }
        },
        MoreExecutors.directExecutor());
  }

  IssueCommandRequest createWipeRequest(
      ImmutableList<WipeDataFlag> wipeDataFlags, String wipeReason) {
    return IssueCommandRequest.builder()
        .setWipe(
            Wipe.builder()
                .setWipeDataFlags(wipeDataFlags)
                .setWipeReason(wipeReason)
                .build())
        .build();
  }
...

Get Command

एक्सटेंशन ऐप्लिकेशन, पहले जारी किए गए कमांड के अनुरोधों की स्थिति के बारे में क्वेरी कर सकता है. किसी निर्देश की स्थिति जानने के लिए, आपको निर्देश आईडी की ज़रूरत होगी. यह आईडी, निर्देश जारी करने के अनुरोध से मिलता है. यहां दिए गए स्निपेट में, एडीपी को 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. अपने ऐप्लिकेशन को COMPANION_APP की भूमिका असाइन करने के लिए, ऐप्लिकेशन की नीति को कॉन्फ़िगर करें. इसके लिए, नीति कॉन्फ़िगरेशन देखें.

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

नीति कॉन्फ़िगरेशन

कंपैनियन ऐप्लिकेशन को सीधे तौर पर एडीपी के साथ कम्यूनिकेट करने की अनुमति देने के लिए, ईएमएम को ऐप्लिकेशन की नीति में roles फ़ील्ड का इस्तेमाल करके, ऐप्लिकेशन को COMPANION_APP की भूमिका असाइन करनी होगी:

 "applications": [{
   "packageName": "com.amapi.extensibility.demo",
   "installType": "FORCE_INSTALLED",
   "roles": [
     { "roleType": "COMPANION_APP" }
   ]
 }]

कंपैनियन ऐप्लिकेशन को लोकल Wipe कमांड जारी करने की अनुमति देने के लिए, extraCapabilities.localDeviceWipeCommand को LOCAL_DEVICE_WIPE_COMMAND_ALLOWED पर सेट करें:

 "applications": [{
   "packageName": "com.amapi.extensibility.demo",
   "installType": "FORCE_INSTALLED",
   "roles": [
     {
       "roleType": "COMPANION_APP",
       "extraCapabilities": {
         "localDeviceWipeCommand": "LOCAL_DEVICE_WIPE_COMMAND_ALLOWED"
       }
     }
   ]
 }]

उपलब्ध अन्य विकल्पों के लिए, ऐप्लिकेशन की भूमिकाओं से जुड़ी नीतियों के साथ डिवाइस को सेट अप करना लेख पढ़ें.

कमांड की स्थिति में होने वाले बदलावों को सुनने वाली सेवा का पता, एडीपी अपने-आप लगा लेता है. इसके लिए, वह ऐप्लिकेशन के मेनिफ़ेस्ट में मौजूद मेटाडेटा का इस्तेमाल करता है. अब नीति में इसे notificationReceiver के तौर पर बताने की ज़रूरत नहीं है. अपने ऐप्लिकेशन और मेनिफ़ेस्ट को तैयार करने के तरीके के बारे में जानने के लिए, ऐप्लिकेशन की भूमिकाएं मैनेज करना लेख पढ़ें.

टेस्ट करना

यूनिट टेस्टिंग

LocalCommandClient एक इंटरफ़ेस है. इसलिए, इसकी मदद से टेस्ट किया जा सकने वाला इंप्लिमेंटेशन उपलब्ध कराया जा सकता है.

इंटिग्रेशन टेस्टिंग

एडीपी के साथ टेस्ट करने के लिए, यह जानकारी ज़रूरी होगी:

  1. एक्सटेंशन ऐप्लिकेशन के पैकेज का नाम.
  2. ऐप्लिकेशन पैकेज से जुड़े सिग्नेचर का base64-एन्कोडेड SHA-256 हैश.
  3. अगर कॉलबैक की जांच की जा रही है, तो कॉलबैक की सुविधा देने वाली नई सेवा का पूरा नाम डालें. उदाहरण में, CommandService का पूरी तरह क्वालिफ़ाइड नाम.