Device Trust from Android Enterprise - इंटिग्रेशन गाइड

डिवाइस के भरोसेमंद होने के सिग्नल पाने के लिए, AMAPI SDK टूल का इस्तेमाल करने के बारे में जानने के लिए, यह दस्तावेज़ आपकी मुख्य गाइड होनी चाहिए.

AMAPI SDK की मदद से, आपका ऐप्लिकेशन Android डिवाइस से जुड़ी नीति (ADP) ऐप्लिकेशन से डिवाइस के भरोसेमंद होने के सिग्नल ऐक्सेस कर सकता है. इसके बाद, आपका ऐप्लिकेशन इन सिग्नल का इस्तेमाल करके, डिवाइस के भरोसेमंद होने की स्थिति का पता लगा सकता है. साथ ही, चुने गए कारोबारी नियम लागू कर सकता है.

ज़रूरी शर्तें

  • आपके ऐप्लिकेशन को डिवाइस के भरोसेमंद होने के सिग्नल पढ़ने की अनुमति होनी चाहिए:
    • AMAPI से मैनेज किए जाने वाले डिवाइसों पर कंपैनियन ऐप्लिकेशन: नीति में COMPANION_APP की भूमिका वाले ऐप्लिकेशन, डिवाइस के भरोसेमंद होने के सिग्नल ऐक्सेस कर सकते हैं. इसके लिए, उन्हें पूरी तरह से मैनेज किए जा रहे डिवाइसों पर अनुमति वाली सूची में शामिल होने की ज़रूरत नहीं है. इसके अलावा, वर्क प्रोफ़ाइल से भी सिग्नल ऐक्सेस किए जा सकते हैं. हालांकि, वर्क प्रोफ़ाइल से सिर्फ़ वर्क प्रोफ़ाइल के सिग्नल ऐक्सेस किए जा सकते हैं. ज़्यादा जानकारी के लिए, ऐप्लिकेशन की भूमिकाएं मैनेज करना, नीति कॉन्फ़िगरेशन, और कंपैनियन ऐप्लिकेशन से सिग्नल ऐक्सेस करना देखें.
    • अन्य सभी ऐप्लिकेशन और एनवायरमेंट: किसी निजी प्रोफ़ाइल, मैनेज नहीं किए जा रहे डिवाइस, कस्टम डीपीसी से मैनेज किए जा रहे डिवाइस या COMPANION_APP की भूमिका के बिना, डिवाइस के भरोसेमंद सिग्नल ऐक्सेस करने के लिए, आपके ऐप्लिकेशन को अनुमति वाली सूची में शामिल होना चाहिए. आवेदन करने के तरीके के बारे में जानने के लिए, डिवाइस के ट्रस्ट सिग्नल ऐक्सेस करने वाले पेज पर जाएं.
  • Android Enterprise, आपके क्लाइंट ऐप्लिकेशन में Play Integrity API के सुइट को इंटिग्रेट करने का सुझाव देता है. साथ ही, डिवाइस के भरोसेमंद होने के सिग्नल को पढ़ने और उन पर भरोसा करने से पहले, नतीजे देखने का सुझाव देता है. जिन डिवाइसों पर Play Integrity API की जांच पूरी नहीं हो पाती है उन पर भरोसा नहीं किया जाना चाहिए. साथ ही, डिवाइस से मिले किसी भी सिग्नल का इस्तेमाल, भरोसेमंद होने की स्थिति का पता लगाने के लिए नहीं किया जाना चाहिए. ज़्यादा जानकारी के लिए, Play Integrity का दस्तावेज़ देखें.

अपने ऐप्लिकेशन में AMAPI SDK टूल को इंटिग्रेट करना

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

ज़रूरी अनुमतियां जोड़ना

Device Trust from Android Enterprise API से मिले कुछ सिग्नल के लिए, यह ज़रूरी है कि ऐप्लिकेशन उसी अनुमति का एलान करे जो इस जानकारी को ऐक्सेस करने के लिए ज़रूरी है. खास तौर पर:

सिग्नल अनुमति ज़रूरी है
नेटवर्क स्टेट ACCESS_NETWORK_STATE
स्क्रीन लॉक की जटिलता REQUEST_PASSWORD_COMPLEXITY

अगर ये अनुमतियां ऐप्लिकेशन के AndroidManifest.xml में शामिल नहीं हैं, तो Device Trust from Android Enterprise API, सिग्नल के मेटाडेटा में PERMISSION_ISSUE दिखाएगा:

internalDeviceSettings=DeviceSettings{
  screenLockComplexity=COMPLEXITY_UNSPECIFIED,
  internalScreenLockComplexityMetadata=Metadata{
    dataIssues=[
      DataIssue{
        issueType=PERMISSION_ISSUE,
        issueLevel=WARNING,
        issueDetails=IssueDetailsCase{none}
      }
    ]
  },

ज़्यादा जानकारी के लिए, डिवाइस के लिए उपलब्ध ट्रस्ट सिग्नल की सूची देखें.

डिवाइस के भरोसेमंद होने के सिग्नल ऐक्सेस करने का तरीका

अनुमति वाली सूची में शामिल ऐप्लिकेशन (इनमें निजी प्रोफ़ाइल में या मैनेज नहीं किए जा रहे डिवाइस पर चल रहे ऐप्लिकेशन शामिल हैं) को यह पुष्टि करनी होगी कि क्लाइंट एनवायरमेंट अप-टू-डेट है. साथ ही, सिग्नल का अनुरोध करने से पहले, ज़रूरत पड़ने पर उसे तैयार करना होगा.

अनुमति वाली सूची में शामिल ऐप्लिकेशन, डिवाइस के भरोसेमंद होने के सिग्नल ऐक्सेस कर सकते हैं. इसके लिए, उन्हें यह तरीका अपनाना होगा:

डिवाइस के भरोसेमंद होने के सिग्नल ऐक्सेस करने का तरीका

क्लाइंट एनवायरमेंट की पुष्टि करना

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

Kotlin

import com.google.android.managementapi.common.model.Role
import com.google.android.managementapi.device.DeviceClient
import com.google.android.managementapi.device.DeviceClientFactory
import com.google.android.managementapi.device.model.GetDeviceRequest
import com.google.android.managementapi.environment.EnvironmentClient
import com.google.android.managementapi.environment.EnvironmentClientFactory
import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.INSTALLED
import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.NOT_INSTALLED
import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.READY
import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.Version.UP_TO_DATE
import com.google.android.managementapi.environment.model.GetEnvironmentRequest
import com.google.android.managementapi.environment.model.PrepareEnvironmentRequest

try {
    val context = applicationContext

    val roles = listOf(Role.builder().setRoleType(Role.RoleType.IDENTITY_PROVIDER).build())
    val request = GetEnvironmentRequest.builder().setRoles(roles).build()
    val environmentClient = EnvironmentClientFactory.create(context)
    val environmentResponse = environmentClient.getEnvironment(request)

    if (environmentResponse.hasAndroidDevicePolicyEnvironment()) {
        val adpEnvironment = environmentResponse.androidDevicePolicyEnvironment

        if (adpEnvironment.state == READY && adpEnvironment.version == UP_TO_DATE) {
            // AMAPI Environment State OK, Version OK. Requesting Device signals..
            checkDevice(deviceClient)
        } else if (adpEnvironment.state == INSTALLED) {
            // prepareEnvironment should be called, calling
            // prepareEnvironment won't show the UI
            prepareEnvironment(context, environmentClient)
        } else if (adpEnvironment.state == NOT_INSTALLED) {
            // prepareEnvironment should be called, calling
            // prepareEnvironment will show the UI
            prepareEnvironment(context, environmentClient)
        }
    }
} catch (e: Exception) {
    Log.e(TAG, "Exception", e)
}

Java

import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.INSTALLED;
import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.NOT_INSTALLED;
import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.State.READY;
import static com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment.Version.UP_TO_DATE;

import com.google.android.managementapi.common.model.Role;
import com.google.android.managementapi.device.DeviceClient;
import com.google.android.managementapi.device.DeviceClientFactory;
import com.google.android.managementapi.device.model.Device;
import com.google.android.managementapi.device.model.GetDeviceRequest;
import com.google.android.managementapi.environment.EnvironmentClient;
import com.google.android.managementapi.environment.EnvironmentClientFactory;
import com.google.android.managementapi.environment.model.Environment;
import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment;
import com.google.android.managementapi.environment.model.GetEnvironmentRequest;
import com.google.android.managementapi.environment.model.PrepareEnvironmentRequest;
import com.google.android.managementapi.environment.model.PrepareEnvironmentResponse;

try {
    Context context = getApplicationContext();

    ImmutableList roles = new ImmutableList.Builder()
            .add(Role.builder()
                    .setRoleType(Role.RoleType.IDENTITY_PROVIDER)
                    .build())
            .build();

    EnvironmentClient environmentClient = EnvironmentClientFactory.create(context);
    GetEnvironmentRequest request = GetEnvironmentRequest.builder()
            .setRoles(roles)
            .build();

    ListenableFuture getEnvironmentFuture = environmentClient.getEnvironmentAsync(request);
    Futures.addCallback(getEnvironmentFuture, new FutureCallback<>() {
        @Override
        public void onSuccess(Environment environment) {
            AndroidDevicePolicyEnvironment adpEnvironment = environment.getAndroidDevicePolicyEnvironment();

            AndroidDevicePolicyEnvironment.State state = adpEnvironment.getState();
            AndroidDevicePolicyEnvironment.Version version = adpEnvironment.getVersion();
            if (state == READY && version == UP_TO_DATE) {
                // AMAPI Environment State OK, Version OK. Requesting Device signals..
                checkDevice(deviceClient);
            } else if (state == INSTALLED) {
                // prepareEnvironment should be called, calling
                // prepareEnvironment won't show the UI
                prepareEnvironment(context, environmentClient);
            } else if (state == NOT_INSTALLED) {
                // prepareEnvironment should be called, calling
                // prepareEnvironment will show the UI
                prepareEnvironment(context, environmentClient);
            }
        }

        @Override
        public void onFailure(Throwable t) {
            Log.d(TAG, t.toString());
        }
    }, MoreExecutors.directExecutor());
} catch (Exception e) {
    Log.d(TAG, e.toString());
}

अगर एडीपी ऐप्लिकेशन इंस्टॉल है, लेकिन अप-टू-डेट नहीं है, तो आपके ऐप्लिकेशन को prepareEnvironment को कॉल करना चाहिए, ताकि उपयोगकर्ता के इंटरैक्शन के बिना एडीपी ऐप्लिकेशन को अपडेट किया जा सके.

अगर एडीपी ऐप्लिकेशन इंस्टॉल नहीं है, तो आपका ऐप्लिकेशन prepareEnvironment को कॉल करके, उपयोगकर्ता को एडीपी ऐप्लिकेशन इंस्टॉल करने के लिए कह सकता है. क्लाइंट एनवायरमेंट तैयार करना देखें.

क्लाइंट एनवायरमेंट तैयार करना

  • अगर एडीपी ऐप्लिकेशन पहले से इंस्टॉल है, तो एपीआई उसे बिना किसी सूचना के अपडेट कर देगा. इसके लिए, उपयोगकर्ता को कुछ करने की ज़रूरत नहीं होगी.

  • अगर एडीपी ऐप्लिकेशन इंस्टॉल नहीं है, तो एपीआई उपयोगकर्ता को एडीपी ऐप्लिकेशन इंस्टॉल करने के लिए कहेगा.

Android Device Policy ऐप्लिकेशन इंस्टॉल करें

उपयोगकर्ता की पसंद पर नज़र रखने के लिए, कॉलबैक रजिस्टर किया जा सकता है. ज़्यादा जानकारी के लिए, एडीपी ऐप्लिकेशन इंस्टॉल करने के दौरान उपयोगकर्ता के इंटरैक्शन को ट्रैक करना लेख पढ़ें.

हमारा सुझाव है कि prepareEnvironment कॉल, यूज़र एक्सपीरियंस (यूएक्स) फ़्लो में शामिल होने के दौरान, फ़ोरग्राउंड प्रोसेस से किया जाए. इससे उपयोगकर्ता को Android Device Policy इंस्टॉल करें मॉडल डायलॉग से हैरान होने से बचाया जा सकता है. अगर फ़ोरग्राउंड प्रोसेस से कॉल करना मुमकिन नहीं है, क्योंकि यह एक वेब फ़्लो है और Android कॉम्पोनेंट में कोई यूज़र इंटरफ़ेस (यूआई) नहीं है, तो बैकग्राउंड से कॉल करने की अनुमति है. हालांकि, इसके लिए ज़रूरी है कि ऐसा ऑनबोर्डिंग उपयोगकर्ता अनुभव फ़्लो के दौरान हो.

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

Kotlin

try {
    val myNotificationReceiverService = ComponentName(
        context, MyNotificationReceiverService::class.java
    )

    val roles = listOf(Role.builder().setRoleType(Role.RoleType.IDENTITY_PROVIDER).build())
    val request = PrepareEnvironmentRequest.builder().setRoles(roles).build()

    val response =
        environmentClient.prepareEnvironment(request, myNotificationReceiverService)

    val environment = response.environment
    val adpEnvironment = environment.androidDevicePolicyEnvironment

    val state = adpEnvironment.state
    val version = adpEnvironment.version
    if (state == READY && version == UP_TO_DATE) {
        // Environment is prepared, access device posture signals using
        // DeviceClient.
        checkDevice(deviceClient)
    } else {
        // The prepareEnvironment call failed to prepare
        Log.w(
            TAG, "AMAPI environment was not ready: " + state + " - " + version
        )
    }

} catch (e: java.lang.Exception) {
    Log.d(TAG, e.toString())
}

Java

try {
    ComponentName myNotificationReceiverService = new ComponentName(
            context,
            MyNotificationReceiverService.class
    );

    ImmutableList roles = new ImmutableList.Builder()
            .add(Role.builder()
                    .setRoleType(Role.RoleType.IDENTITY_PROVIDER)
                    .build())
            .build();


    PrepareEnvironmentRequest request = PrepareEnvironmentRequest.builder()
            .setRoles(roles)
            .build();

    ListenableFuture environmentFuture =
            environmentClient.prepareEnvironmentAsync(
                    request,
                    myNotificationReceiverService
            );

    Futures.addCallback(environmentFuture, new FutureCallback<>() {
        @Override
        public void onSuccess(PrepareEnvironmentResponse response) {
            Environment environment = response.getEnvironment();
            AndroidDevicePolicyEnvironment adpEnvironment = environment.getAndroidDevicePolicyEnvironment();

            AndroidDevicePolicyEnvironment.State state = adpEnvironment.getState();
            AndroidDevicePolicyEnvironment.Version version = adpEnvironment.getVersion();
            if (state == READY && version == UP_TO_DATE) {
                // AMAPI Environment State OK, Version OK. Requesting Device signals..
                checkDevice(deviceClient);
            } else {
                // The prepareEnvironment call failed to prepare
                Log.w(
                        TAG, "AMAPI environment was not ready: "
                        + adpEnvironment.getState() + " - " + adpEnvironment.getVersion()
                );
            }
        }

        @Override
        public void onFailure(@NonNull Throwable t) {
            // Handle the error
            Log.d(TAG, "AMAPI response did not contain an ADP environment");
        }
    }, MoreExecutors.directExecutor());
} catch (Exception e) {
    Log.d(TAG, e.toString());
}

डिवाइस के सुरक्षा सिग्नल ऐक्सेस करना

DeviceClient के इस्तेमाल से जुड़ा सुझाव

deviceClient इंस्टेंस (या EnvironmentClient इंस्टेंस) बनाने से, Android Device Policy (ADP) ऐप्लिकेशन के साथ कम्यूनिकेशन चैनल सेट अप हो जाता है. यह चैनल, इस्तेमाल न होने पर अपने-आप अनबाइंड हो जाता है. क्लाइंट इंस्टेंस, बंद करने का कोई साफ़ तरीका नहीं दिखाते. इसलिए, कई इंस्टेंस बनाने और उन्हें खारिज करने से, ऐसे चैनल रह जाते हैं जिनका कोई मालिक नहीं होता. इन्हें गार्बेज-कलेक्ट किया जाता है.

परफ़ॉर्मेंस को ऑप्टिमाइज़ करने और बिना पैरंट वाले चैनलों से बचने के लिए, DeviceClientFactory.create(context.applicationContext) का इस्तेमाल करके ऐप्लिकेशन स्कोप पर DeviceClient का एक इंस्टेंस बनाएं. साथ ही, इसे पूरे ऐप्लिकेशन में फिर से इस्तेमाल करने के लिए कैश मेमोरी में सेव करें. उदाहरण के लिए, ऐप्लिकेशन-स्कोप वाले सिंगलटन के तौर पर या डिपेंडेंसी इंजेक्शन का इस्तेमाल करके.

अपनी पसंद के डिवाइस के भरोसेमंद सिग्नल ऐक्सेस करने के लिए, कैश मेमोरी में सेव किए गए deviceClient इंस्टेंस का इस्तेमाल करके, Device ऑब्जेक्ट का अनुरोध करें:

Kotlin

runCatching {
    deviceClient.getDeviceAwait(GetDeviceRequest.getDefaultInstance())
}.onFailure { t ->
    Log.d(TAG, t.toString())
}.onSuccess { device ->
    // Access device posture signals available in device
    val deviceString = device.toString()
    Log.d(TAG, deviceString)
}

Java

ListenableFuture deviceFuture =
        deviceClient.getDevice(GetDeviceRequest.getDefaultInstance());

Futures.addCallback(deviceFuture, new FutureCallback() {
    @Override
    public void onSuccess(Device device) {
        // Access device posture signals available in device
        String deviceString = device.toString();
        Log.d(TAG, deviceString);
    }

    @Override
    public void onFailure(Throwable t) {
        Log.d(TAG, t.toString());
    }
}, MoreExecutors.directExecutor());

कंपैनियन ऐप्लिकेशन से सिग्नल ऐक्सेस करना

पूरी तरह से मैनेज किए जा रहे डिवाइसों पर या Android Management API (AMAPI) की मदद से मैनेज की जा रही वर्क प्रोफ़ाइल में, COMPANION_APP की भूमिका वाला ऐप्लिकेशन, अनुमति वाली सूची में रजिस्टर हुए बिना भी डिवाइस के सुरक्षा सिग्नल पढ़ सकता है.

जब आपके ऐप्लिकेशन को वर्क प्रोफ़ाइल (कंपनी के मालिकाना हक वाले या निजी डिवाइस पर) से कॉल किया जाता है, तो उसे वर्क प्रोफ़ाइल में ही चलना चाहिए. साथ ही, ऐप्लिकेशन को सिर्फ़ वर्क प्रोफ़ाइल से मिलने वाले सिग्नल का ऐक्सेस होना चाहिए. उदाहरण के लिए, मैनेजमेंट की स्थिति, स्क्रीन लॉक की जटिलता, और इंस्टॉल किए गए ऐप्लिकेशन सिर्फ़ वर्क प्रोफ़ाइल को दिखाते हैं.

1. नीति में COMPANION_APP की भूमिका असाइन करना

applications नीति की सूची में अपने ऐप्लिकेशन को roleType: "COMPANION_APP" देने के लिए, ईएमएम नीति को कॉन्फ़िगर करें:

2. DeviceClient की मदद से, सिग्नल सीधे तौर पर पढ़ना

DeviceClientFactory.create का इस्तेमाल करके, ऐप्लिकेशन के स्कोप में एक deviceClient इंस्टेंस बनाएं और उसे कैश मेमोरी में सेव करें (DeviceClient के इस्तेमाल से जुड़ा सुझाव देखें). इसके बाद, सीधे Device ऑब्जेक्ट का अनुरोध करें:

Kotlin

import android.content.Context
import android.util.Log
import com.google.android.managementapi.device.DeviceClient
import com.google.android.managementapi.device.DeviceClientFactory
import com.google.android.managementapi.device.model.GetDeviceRequest

// Instantiate once at application scope (for example, using dependency injection)
// to reuse a single DeviceClient instance across your app.
class DeviceTrustRepository(context: Context) {
    private val deviceClient: DeviceClient =
        DeviceClientFactory.create(context.applicationContext)

    suspend fun readSignalsFromCompanionApp() {
        runCatching {
            deviceClient.getDeviceAwait(GetDeviceRequest.getDefaultInstance())
        }.onSuccess { device ->
            Log.d(TAG, "Device signals: $device")
        }.onFailure { t ->
            Log.e(TAG, "Failed to read device signals", t)
        }
    }

    companion object {
        private const val TAG = "DeviceTrustRepository"
    }
}

Java

import android.content.Context;
import android.util.Log;
import com.google.android.managementapi.device.DeviceClient;
import com.google.android.managementapi.device.DeviceClientFactory;
import com.google.android.managementapi.device.model.Device;
import com.google.android.managementapi.device.model.GetDeviceRequest;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;

// Instantiate once at application scope (for example, using dependency injection)
// to reuse a single DeviceClient instance across your app.
public class DeviceTrustRepository {
    private static final String TAG = "DeviceTrustRepository";
    private final DeviceClient deviceClient;

    public DeviceTrustRepository(Context context) {
        this.deviceClient = DeviceClientFactory.create(context.getApplicationContext());
    }

    public void readSignalsFromCompanionApp() {
        ListenableFuture deviceFuture =
                deviceClient.getDevice(GetDeviceRequest.getDefaultInstance());

        Futures.addCallback(deviceFuture, new FutureCallback() {
            @Override
            public void onSuccess(Device device) {
                Log.d(TAG, "Device signals: " + device);
            }

            @Override
            public void onFailure(Throwable t) {
                Log.e(TAG, "Failed to read device signals", t);
            }
        }, MoreExecutors.directExecutor());
    }
}

गड़बड़ियां ठीक करना

अगर आपका ऐप्लिकेशन, डिवाइस पर भरोसा करने का अनुरोध करता है और कॉल पूरा नहीं होता है, तो आपके ऐप्लिकेशन को एक अपवाद मिलता है. ये अपवाद कई वजहों से हो सकते हैं, जैसे:

  • SecurityException - आपके ऐप्लिकेशन के पास अनुरोध करने की अनुमति नहीं है. उदाहरण के लिए, आपके ऐप्लिकेशन को अनुमति वाली सूची में रजिस्टर नहीं किया गया है, जबकि ऐसा करना ज़रूरी है. इसके अलावा, AMAPI से मैनेज किए जा रहे डिवाइस पर, ऐप्लिकेशन को COMPANION_APP की भूमिका असाइन नहीं की गई है या prepareEnvironment को ऐसे कंपैनियन ऐप्लिकेशन के तौर पर कॉल किया गया है जो अनुमति वाली सूची में शामिल नहीं है. डिवाइस के भरोसेमंद सिग्नल का ऐक्सेस और कंपैनियन ऐप्लिकेशन से सिग्नल ऐक्सेस करना देखें.
  • AmapiSdkException की सबक्लास - एडीपी मौजूद नहीं है या तैयार नहीं है. ऐसा कुछ समय के लिए हो सकता है. इसलिए, आपको फिर से कॉल करना चाहिए.

फिर से कोशिश करने की रणनीतियां

कुछ समय के लिए होने वाली गड़बड़ियों को ठीक करने के लिए, एक्स्पोनेंशियल बैकऑफ़ के साथ फिर से कोशिश करने की रणनीति लागू करें. पहली बार कोशिश करने पर, अगर अनुरोध पूरा नहीं होता है, तो पांच सेकंड बाद फिर से कोशिश करें.

फिर से कोशिश करने की रणनीति लागू करें. इसमें कोशिश करने की ज़्यादा से ज़्यादा संख्या को एग्ज़िट की शर्त के तौर पर इस्तेमाल करें. इसके लिए, हर बार तेज़ी से बढ़ते हुए समय (10 सेकंड, 20 सेकंड वगैरह) का इस्तेमाल करें.

एडीपी ऐप्लिकेशन इंस्टॉल करने के दौरान, उपयोगकर्ता के इंटरैक्शन को ट्रैक करना

अगर डिवाइस को prepareEnvironment के दौरान एडीपी ऐप्लिकेशन इंस्टॉल करना है, तो आपका ऐप्लिकेशन उपयोगकर्ता के इंटरैक्शन को ट्रैक कर सकता है. इसके लिए, उसे NotificationReceiverService को लागू करना होगा, ताकि getPrepareEnvironmentListener को ओवरराइड करने वाली सूचनाएं मिल सकें:

Kotlin

import android.util.Log
import com.google.android.managementapi.environment.EnvironmentListener
import com.google.android.managementapi.environment.model.EnvironmentEvent.EventCase.Kind.ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED
import com.google.android.managementapi.environment.model.EnvironmentEvent
import com.google.android.managementapi.notification.NotificationReceiverService

class MyNotificationReceiverService : NotificationReceiverService() {
    override fun getPrepareEnvironmentListener(): EnvironmentListener {
        return MyEnvironmentListener()
    }
}

class MyEnvironmentListener : EnvironmentListener {
    override fun onEnvironmentEvent(
        event: EnvironmentEvent
    ) {
        if (event.event.kind == ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED) {
            Log.d(TAG, "User provided install consent")
        } else {
            Log.d(TAG, "User rejected install consent")
        }
    }

    companion object {
        private val TAG: String = MyEnvironmentListener::class.java.simpleName
    }
}

Java

import static com.google.android.managementapi.environment.model.EnvironmentEvent.EventCase.Kind.ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED;

import android.util.Log;
import androidx.annotation.NonNull;
import com.google.android.managementapi.environment.EnvironmentListener;
import com.google.android.managementapi.environment.model.EnvironmentEvent;
import com.google.android.managementapi.notification.NotificationReceiverService;

class MyNotificationReceiverService extends NotificationReceiverService {
    @NonNull
    @Override
    protected EnvironmentListener getPrepareEnvironmentListener() {
        return new MyEnvironmentListener();
    }
}
class MyEnvironmentListener implements EnvironmentListener {
    final private String TAG = MyEnvironmentListener.class.getSimpleName();

    @Override
    public void onEnvironmentEvent(EnvironmentEvent event) {
        if (event.getEvent().getKind() == ANDROID_DEVICE_POLICY_INSTALL_CONSENT_ACCEPTED)
        {
            Log.d(TAG, "User provided install consent");
        } else {
            Log.d(TAG, "User rejected install consent");
        }
    }
}

ज्ञात समस्याएं

फ़िलहाल, ऐसी किसी समस्या की जानकारी नहीं है.