AMAPI SDK की मदद से, Unified Update Controls को कॉन्फ़िगर करना

इस गाइड में, कस्टम डिवाइस से जुड़ी नीति कंट्रोलर (डीपीसी) में Android Management API (AMAPI) SDK टूल इस्तेमाल करने का तरीका बताया गया है. इससे कंपनी के मालिकाना हक वाले डिवाइसों पर, अपडेट के लिए यूनिफ़ाइड कंट्रोल (यूयूसी) को कॉन्फ़िगर किया जा सकता है.

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

शुरू करने से पहले, Unified Update Controls पढ़ें. इससे आपको यह जानने में मदद मिलेगी कि नियम, टारगेट, प्रेडिकेट, और नतीजे कैसे काम करते हैं. साथ ही, आपको यह भी पता चलेगा कि सभी यूयूसी इंटिग्रेशन पर कौनसी सीमाएं लागू होती हैं.

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

अपने कस्टम डीपीसी में यूयूसी को इंटिग्रेट करने से पहले, इन ज़रूरी शर्तों की पुष्टि करें:

अपने कस्टम डीपीसी में AMAPI SDK टूल को इंटिग्रेट करना

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

यूनिफ़ाइड अपडेट कंट्रोल को कॉन्फ़िगर करने का तरीका

अपने कस्टम डीपीसी से यूयूसी की नीतियां कॉन्फ़िगर करने के लिए, यह पक्का करें कि उपयोगकर्ता के डिवाइस पर मौजूद क्लाइंट एनवायरमेंट तैयार और अप-टू-डेट हो. इसके बाद ही, एडीपी को नीति से जुड़े अनुरोध भेजें:

  1. क्लाइंट एनवायरमेंट की पुष्टि करना
  2. क्लाइंट एनवायरमेंट तैयार करना
  3. अपडेट की नीति सेट करना, वापस पाना, और मिटाना

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

इस उदाहरण में, Kotlin में getEnvironment या Java में getEnvironmentAsync को Role.RoleType.DEVICE_POLICY_CONTROLLER के साथ कॉल करने का तरीका बताया गया है. इससे एडीपी ऐप्लिकेशन की स्थिति की जांच की जा सकती है. अगर एनवायरमेंट READY और UP_TO_DATE है, तो आपका कस्टम डीपीसी, PolicyClient का इस्तेमाल करके यूयूसी की नीतियां कॉन्फ़िगर कर सकता है. इसके अलावा, ADP ऐप्लिकेशन को इंस्टॉल या अपडेट करने के लिए, prepareEnvironment पर कॉल करें. इसके लिए, क्लाइंट एनवायरमेंट तैयार करना देखें.

Kotlin

import android.content.Context
import android.util.Log
import com.google.android.managementapi.common.model.Role
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

private suspend fun checkEnvironmentForUuc(context: Context): Boolean {
    try {
        val roles = listOf(
            Role.builder()
                .setRoleType(Role.RoleType.DEVICE_POLICY_CONTROLLER)
                .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

            when (adpEnvironment.state) {
                READY -> {
                    return if (adpEnvironment.version == UP_TO_DATE) {
                        // AMAPI environment state and version are ready.
                        true
                    } else {
                        prepareEnvironment(context, environmentClient)
                    }
                }

                INSTALLED -> {
                    // Call prepareEnvironment to silently update ADP.
                    return prepareEnvironment(context, environmentClient)
                }

                NOT_INSTALLED -> {
                    // Call prepareEnvironment to install ADP.
                    return prepareEnvironment(context, environmentClient)
                }

                else -> {}
            }
        }
    } catch (e: Exception) {
        Log.e(TAG, "Exception checking environment", e)
    }
    return false
}

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 android.content.Context;
import android.util.Log;
import com.google.android.managementapi.common.model.Role;
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.common.collect.ImmutableList;
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;

private void checkEnvironmentForUuc(Context context) {
    try {
        ImmutableList roles = new ImmutableList.Builder()
                .add(Role.builder()
                        .setRoleType(Role.RoleType.DEVICE_POLICY_CONTROLLER)
                        .build())
                .build();

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

        ListenableFuture getEnvironmentFuture =
                environmentClient.getEnvironmentAsync(getRequest);
        Futures.addCallback(getEnvironmentFuture, new FutureCallback() {
            @Override
            public void onSuccess(Environment environment) {
                if (!environment.hasAndroidDevicePolicyEnvironment()) {
                    return;
                }
                AndroidDevicePolicyEnvironment adpEnvironment =
                        environment.getAndroidDevicePolicyEnvironment();

                AndroidDevicePolicyEnvironment.State state = adpEnvironment.getState();
                AndroidDevicePolicyEnvironment.Version version = adpEnvironment.getVersion();
                if (state == READY && version == UP_TO_DATE) {
                    // AMAPI environment state and version are ready.
                    return;
                } else if (state == INSTALLED || state == NOT_INSTALLED) {
                    // Call prepareEnvironment to silently install or update ADP.
                    prepareEnvironment(context, environmentClient);
                }
            }

            @Override
            public void onFailure(Throwable t) {
                Log.e(TAG, "Failed to verify environment", t);
            }
        }, MoreExecutors.directExecutor());
    } catch (Exception e) {
        Log.e(TAG, "Exception verifying environment", e);
    }
}

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

अगर डिवाइस पर एनवायरमेंट तैयार या अप-टू-डेट नहीं है, तो PolicyClient का इस्तेमाल करने से पहले prepareEnvironment को कॉल करें.

जब Role.RoleType.DEVICE_POLICY_CONTROLLER के साथ कस्टम डीपीसी से कॉल किया जाता है और आपके डीपीसी के DeviceAdminReceiver कॉम्पोनेंट का नाम setAdmin() को पास किया जाता है, तो prepareEnvironment, एडीपी ऐप्लिकेशन को साइलेंट तरीके से इंस्टॉल करता है (अगर पहले से इंस्टॉल नहीं है). साथ ही, उपयोगकर्ता के इंटरैक्शन के बिना, एडीपी ऐप्लिकेशन और Google Play Store को अपडेट करता है. कस्टम डीपीसी फ़्लो में एनवायरमेंट तैयार करने के बारे में ज़्यादा जानकारी के लिए, एनवायरमेंट तैयार करना और उपयोगकर्ता को रजिस्टर करना लेख पढ़ें.

दिखता है.

Kotlin

import android.content.ComponentName
import android.content.Context
import android.util.Log
import com.google.android.managementapi.common.model.Role
import com.google.android.managementapi.environment.EnvironmentClient
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.PrepareEnvironmentRequest

private suspend fun prepareEnvironment(
    context: Context,
    environmentClient: EnvironmentClient
): Boolean {
    try {
        val roles = listOf(
            Role.builder()
                .setRoleType(Role.RoleType.DEVICE_POLICY_CONTROLLER)
                .build()
        )
        val request = PrepareEnvironmentRequest.builder()
            .setRoles(roles)
            .setAdmin(
                ComponentName(
                    context,
                    DeviceAdminReceiver::class.java
                )
            )
            .build()

        val response = environmentClient.prepareEnvironment(request, null)

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

        val state = adpEnvironment.state
        val version = adpEnvironment.version
        return (state == READY && version == UP_TO_DATE)
    } catch (e: Exception) {
        Log.e(TAG, "Failed to prepare environment", e)
    }
    return false
}

Java

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 android.content.ComponentName;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import com.google.android.managementapi.common.model.Role;
import com.google.android.managementapi.environment.EnvironmentClient;
import com.google.android.managementapi.environment.model.Environment;
import com.google.android.managementapi.environment.model.Environment.AndroidDevicePolicyEnvironment;
import com.google.android.managementapi.environment.model.PrepareEnvironmentRequest;
import com.google.android.managementapi.environment.model.PrepareEnvironmentResponse;
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.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;

private void prepareEnvironment(Context context, EnvironmentClient environmentClient) {
    try {
        ImmutableList roles = new ImmutableList.Builder()
                .add(Role.builder()
                        .setRoleType(Role.RoleType.DEVICE_POLICY_CONTROLLER)
                        .build())
                .build();

        ComponentName adminComponent = new ComponentName(
                context,
                DeviceAdminReceiver.class
        );

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

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

        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) {
                    // Environment is prepared; configure UUC policy using PolicyClient.
                } else {
                    Log.w(
                            TAG,
                            "AMAPI environment was not ready: " + state + " - " + version
                    );
                }
            }

            @Override
            public void onFailure(@NonNull Throwable t) {
                Log.e(TAG, "Failed to prepare environment", t);
            }
        }, MoreExecutors.directExecutor());
    } catch (Exception e) {
        Log.e(TAG, "Exception preparing environment", e);
    }
}

अपडेट की नीति को सेट करना, वापस पाना, और हटाना

एनवायरमेंट तैयार होने के बाद, PolicyClient (PolicyClientFactory.create(context) की मदद से बनाया गया) का इस्तेमाल करके, Policy लागू करें. इसमें आपके UnifiedUpdatePolicy नियम शामिल होने चाहिए. इसके अलावा, चालू नीति की जांच करें या डिवाइस से यूयूसी नीति को हटाएं.

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

PolicyClient इंस्टेंस बनाने से, ADP ऐप्लिकेशन के साथ कम्यूनिकेशन चैनल सेट अप हो जाता है. परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए, हमारा सुझाव है कि आप PolicyClientFactory.create() का इस्तेमाल करके PolicyClient का एक इंस्टेंस बनाएं. साथ ही, इसे कैश मेमोरी में सेव करें, ताकि आप अपने पूरे ऐप्लिकेशन में इसका दोबारा इस्तेमाल कर सकें. जब कोई PolicyClient इंस्टेंस चालू हो, तब नया इंस्टेंस बनाने से बचें. ऐसा करने से, मौजूदा कम्यूनिकेशन चैनल को बंद करना पड़ सकता है. इससे ओवरहेड बढ़ता है और रिसॉर्स लीक हो सकते हैं.

अपडेट की नीति सेट करना

यूयूसी के नियम लागू करने के लिए, Policy.UnifiedUpdatePolicy बनाएं. इसमें Rule ऑब्जेक्ट की सूची शामिल करें. इसके बाद, इसे UpdatePolicyRequest में मौजूद Policy से अटैच करें. इसके बाद, updatePolicy (Kotlin में) या updatePolicyFuture (Java में) को कॉल करें:

Kotlin

import android.util.Log
import com.google.android.managementapi.policy.PolicyClient
import com.google.android.managementapi.policy.model.Policy
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule
import com.google.android.managementapi.policy.model.UpdatePolicyRequest

suspend fun setUucPolicy(
    policyClient: PolicyClient,
    rules: Iterable
): Boolean {
    // Build the UnifiedUpdatePolicy and attach it to the overall Policy.
    val unifiedUpdatePolicy = Policy.UnifiedUpdatePolicy.builder()
        .setRules(rules)
        .build()

    val policy = Policy.builder()
        .setUnifiedUpdatePolicy(unifiedUpdatePolicy)
        .build()

    // Create the UpdatePolicyRequest.
    val updateRequest = UpdatePolicyRequest.builder()
        .setPolicy(policy)
        .build()

    // Apply the policy using PolicyClient within a CoroutineScope.
    return try {
        val updatedPolicy = policyClient.updatePolicy(updateRequest)
        Log.d(TAG, "Policy updated successfully: $updatedPolicy")
        true
    } catch (e: Exception) {
        Log.e(TAG, "Error updating policy: ${e.message}", e)
        false
    }
}

Java

import android.util.Log;
import com.google.android.managementapi.policy.PolicyClient;
import com.google.android.managementapi.policy.model.Policy;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule;
import com.google.android.managementapi.policy.model.UpdatePolicyRequest;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

ListenableFuture setUucPolicy(
        PolicyClient policyClient,
        Iterable rules
) {
    // Build the UnifiedUpdatePolicy and attach it to the overall Policy.
    UnifiedUpdatePolicy unifiedUpdatePolicy = UnifiedUpdatePolicy.builder()
            .setRules(
                    StreamSupport.stream(rules.spliterator(), false)
                            .collect(Collectors.toList())
            )
            .build();

    Policy policy = Policy.builder()
            .setUnifiedUpdatePolicy(unifiedUpdatePolicy)
            .build();

    // Create the UpdatePolicyRequest.
    UpdatePolicyRequest updateRequest = UpdatePolicyRequest.builder()
            .setPolicy(policy)
            .build();

    // Apply the policy using PolicyClient.
    try {
        ListenableFuture updateFuture =
                policyClient.updatePolicyFuture(updateRequest);
        return Futures.transform(updateFuture, updatedPolicy -> {
            Log.d(TAG, "Policy updated successfully: " + updatedPolicy);
            return true;
        }, MoreExecutors.directExecutor());
    } catch (Exception e) {
        Log.e(TAG, "Error updating policy: " + e.getMessage(), e);
        return Futures.immediateFuture(false);
    }
}

अपडेट की चालू नीति को वापस पाना

डिवाइस पर चालू यूयूसी नीति की जांच करने के लिए, GetPolicyRequest बनाएं और Kotlin में getPolicy या Java में getPolicyFuture को कॉल करें. वापस किए गए Policy पर hasUnifiedUpdatePolicy() का इस्तेमाल करके देखें कि यूयूसी नीति कॉन्फ़िगर की गई है या नहीं:

Kotlin

import android.util.Log
import com.google.android.managementapi.policy.PolicyClient
import com.google.android.managementapi.policy.model.GetPolicyRequest
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule

suspend fun getActiveUucPolicy(policyClient: PolicyClient) {
    try {
        val getPolicyRequest = GetPolicyRequest.builder().build()
        val activePolicy = policyClient.getPolicy(getPolicyRequest)
        Log.i(TAG, "Policy version: ${activePolicy.version}")

        if (!activePolicy.hasUnifiedUpdatePolicy()) {
            Log.i(TAG, "No Unified Update Policy set.")
            return
        }

        val activeUucPolicy = activePolicy.unifiedUpdatePolicy
        val rules: List = activeUucPolicy.rules.toList()
        rules.forEachIndexed { index, rule ->
            val outcome = if (rule.hasOutcome()) rule.outcome.toString() else "[no outcome]"
            val predicate = if (rule.hasPredicate()) rule.predicate.toString() else "[no predicate]"
            Log.i(TAG, "Rule [$index] targets: ${rule.targets}")
            Log.i(TAG, "Rule [$index] outcome: $outcome")
            Log.i(TAG, "Rule [$index] predicate: $predicate")
        }
    } catch (e: Exception) {
        Log.e(TAG, "Error retrieving policy: ${e.message}", e)
    }
}

Java

import android.util.Log;
import com.google.android.managementapi.policy.PolicyClient;
import com.google.android.managementapi.policy.model.GetPolicyRequest;
import com.google.android.managementapi.policy.model.Policy;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule;
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;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

void getActiveUucPolicy(PolicyClient policyClient) {
    try {
        GetPolicyRequest getPolicyRequest = GetPolicyRequest.builder().build();
        ListenableFuture getActivePolicy =
                policyClient.getPolicyFuture(getPolicyRequest);

        Futures.addCallback(getActivePolicy, new FutureCallback() {
            @Override
            public void onSuccess(Policy result) {
                if (!result.hasUnifiedUpdatePolicy()) {
                    Log.i(TAG, "No Unified Update Policy set.");
                    return;
                }

                UnifiedUpdatePolicy activeUucPolicy = result.getUnifiedUpdatePolicy();
                List uucRules = StreamSupport.stream(
                                activeUucPolicy.getRules().spliterator(), false)
                        .collect(Collectors.toList());

                for (int i = 0; i < uucRules.size(); i++) {
                    Rule rule = uucRules.get(i);
                    String outcome = rule.hasOutcome()
                            ? rule.getOutcome().toString() : "[no outcome]";
                    String predicate = rule.hasPredicate()
                            ? rule.getPredicate().toString() : "[no predicate]";
                    Log.i(TAG, "Rule [" + i + "] targets: " + rule.getTargets());
                    Log.i(TAG, "Rule [" + i + "] outcome: " + outcome);
                    Log.i(TAG, "Rule [" + i + "] predicate: " + predicate);
                }
            }

            @Override
            public void onFailure(Throwable t) {
                Log.e(TAG, "Error retrieving policy", t);
            }
        }, MoreExecutors.directExecutor());
    } catch (Exception e) {
        Log.e(TAG, "Exception retrieving policy", e);
    }
}

अपडेट की नीति को मिटाना

Policy पर मौजूद अन्य फ़ील्ड को मिटाए बिना, डिवाइस से UnifiedUpdatePolicy को हटाने के लिए, getPolicy का इस्तेमाल करके मौजूदा Policy को वापस पाएं. इसके बाद, currentPolicy.toBuilder().clearUnifiedUpdatePolicy().build() को कॉल करें और अपडेट किए गए Policy को लागू करें:

Kotlin

import android.util.Log
import com.google.android.managementapi.policy.PolicyClient
import com.google.android.managementapi.policy.model.GetPolicyRequest
import com.google.android.managementapi.policy.model.UpdatePolicyRequest

suspend fun clearUucPolicy(policyClient: PolicyClient): Boolean {
    try {
        // 1. Retrieve the current policy.
        val currentPolicy = policyClient.getPolicy(
            GetPolicyRequest.builder().build()
        )
        if (!currentPolicy.hasUnifiedUpdatePolicy()) {
            Log.i(TAG, "Policy does not have a UnifiedUpdatePolicy to clear.")
            return true
        }

        // 2. Convert to a builder and clear the UnifiedUpdatePolicy field.
        val policyWithUucCleared = currentPolicy.toBuilder()
            .clearUnifiedUpdatePolicy()
            .build()

        // 3. Apply the modified Policy object.
        val updateRequest = UpdatePolicyRequest.builder()
            .setPolicy(policyWithUucCleared)
            .build()
        val updatedPolicy = policyClient.updatePolicy(updateRequest)

        return !updatedPolicy.hasUnifiedUpdatePolicy()
    } catch (e: Exception) {
        Log.e(TAG, "Error clearing policy: ${e.message}", e)
        return false
    }
}

Java

import android.util.Log;
import com.google.android.managementapi.policy.PolicyClient;
import com.google.android.managementapi.policy.model.GetPolicyRequest;
import com.google.android.managementapi.policy.model.Policy;
import com.google.android.managementapi.policy.model.UpdatePolicyRequest;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;

ListenableFuture clearUucPolicy(PolicyClient policyClient) {
    try {
        ListenableFuture currentPolicyFuture =
                policyClient.getPolicyFuture(GetPolicyRequest.builder().build());

        return Futures.transformAsync(currentPolicyFuture, currentPolicy -> {
            if (!currentPolicy.hasUnifiedUpdatePolicy()) {
                Log.i(TAG, "Policy does not have a UnifiedUpdatePolicy to clear.");
                return Futures.immediateFuture(true);
            }

            Policy policyWithUucCleared = currentPolicy.toBuilder()
                    .clearUnifiedUpdatePolicy()
                    .build();

            UpdatePolicyRequest updateRequest = UpdatePolicyRequest.builder()
                    .setPolicy(policyWithUucCleared)
                    .build();

            ListenableFuture updateFuture =
                    policyClient.updatePolicyFuture(updateRequest);

            return Futures.transform(
                    updateFuture,
                    updatedPolicy -> !updatedPolicy.hasUnifiedUpdatePolicy(),
                    MoreExecutors.directExecutor()
            );
        }, MoreExecutors.directExecutor());
    } catch (Exception e) {
        Log.e(TAG, "Error clearing policy: " + e.getMessage(), e);
        return Futures.immediateFuture(false);
    }
}

AOSP SystemUpdatePolicy की प्राथमिकता

कस्टम डीपीसी में, Android कंपैटबिलिटी डेफ़िनिशन डॉक्यूमेंट (CDD) के तहत, डिवाइसों को DevicePolicyManager.setSystemUpdatePolicy के ज़रिए सेट किए गए एओएसपी SystemUpdatePolicy का पालन करना ज़रूरी है.

इस वजह से, ओईएम के ओटीए अपडेट का व्यवहार इस बात पर निर्भर करता है कि डिवाइस पर एओएसपी SystemUpdatePolicy चालू है या नहीं:

  • यूयूसी नीति और एओएसपी SystemUpdatePolicy, दोनों सेट हैं: ओईएम के ओटीए अपडेट के लिए, एओएसपी SystemUpdatePolicy को प्राथमिकता दी जाती है. साथ ही, यूयूसी के टारगेट OS_UPDATE_WITH_API_LEVEL_CHANGE और OS_UPDATE_WITHOUT_API_LEVEL_CHANGE को अनदेखा कर दिया जाता है. अगर आपको यूयूसी से ओईएम के ओटीए अपडेट मैनेज कराने हैं, तो अपने कस्टम डीपीसी में एओएसपी SystemUpdatePolicy को मिटाएं.
  • सिर्फ़ यूयूसी नीति सेट है (एओएसपी SystemUpdatePolicy को हटा दिया गया है): ओईएम ओटीए एजेंट, उन डिवाइसों पर ओईएम ओटीए अपडेट के लिए यूयूसी नीति लागू करता है जिन पर यह सुविधा काम करती है.
  • ऐसे डिवाइस जिन पर ओईएम ओटीए अपडेट के लिए, यूयूसी की सुविधा अब तक उपलब्ध नहीं है: जिन डिवाइसों पर ओईएम ओटीए अपडेट के लिए Android 17 (एपीआई लेवल 37) की ज़रूरत होती है उन पर Google Play के सिस्टम अपडेट (GOOGLE_PLAY_SYSTEM_UPDATE) और Google की सिस्टम सेवाओं (GOOGLE_SYSTEM_SERVICES और SINGLE_APP) को कंट्रोल करने के लिए, यूयूसी का इस्तेमाल किया जा सकता है. साथ ही, ओईएम ओटीए अपडेट के लिए, एओएसपी SystemUpdatePolicy का इस्तेमाल जारी रखा जा सकता है.

DevicePolicyManager का इस्तेमाल करके, यह देखा जा सकता है कि डिवाइस पर AOSP SystemUpdatePolicy चालू है या नहीं:

Kotlin

import android.app.admin.DevicePolicyManager
import android.content.Context

fun Context.isSystemUpdatePolicyActive(): Boolean {
    val dpm = getSystemService(Context.DEVICE_POLICY_SERVICE) as? DevicePolicyManager
    return dpm?.systemUpdatePolicy != null
}

Java

import android.app.admin.DevicePolicyManager;
import android.content.Context;

boolean isSystemUpdatePolicyActive(Context context) {
    DevicePolicyManager dpm =
            (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
    return dpm != null && dpm.getSystemUpdatePolicy() != null;
}

नीति कॉन्फ़िगरेशन के उदाहरण

यहां दिए गए उदाहरणों में, Kotlin और Java में यूयूसी नियम बनाने का तरीका बताया गया है. साथ ही, अपडेट करने की नीति सेट करना, उसे वापस पाना, और उसे मिटाना में बताए गए setUucPolicy हेल्पर का इस्तेमाल करके, उन्हें लागू करने का तरीका बताया गया है. हर फ़ील्ड का मतलब जानने के लिए, यूयूसी की नीतियों को समझना लेख पढ़ें. Unified Update Controls में, ये ही स्थितियां JSON के तौर पर उपलब्ध हैं.

कारोबार के खुले होने के समय, ओएस के मुख्य अपडेट ब्लॉक करना

यहां दिए गए नियम के मुताबिक, सोमवार से शुक्रवार तक सुबह 9:00 बजे से शाम 5:00 बजे तक, ओएस के मुख्य अपडेट (OS_UPDATE_WITH_API_LEVEL_CHANGE) ब्लॉक रहते हैं:

Kotlin

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.BLOCK
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.OS_UPDATE_WITH_API_LEVEL_CHANGE
import java.time.DayOfWeek
import java.time.LocalTime

// 1. Define the target (OS update with API level change).
val target = Target.builder()
    .setTargetType(OS_UPDATE_WITH_API_LEVEL_CHANGE)
    .build()

// 2. Define the predicate (Monday through Friday, 09:00 to 17:00).
val predicate = Predicate.builder()
    .setDaysOfWeek(
        listOf(
            DayOfWeek.MONDAY,
            DayOfWeek.TUESDAY,
            DayOfWeek.WEDNESDAY,
            DayOfWeek.THURSDAY,
            DayOfWeek.FRIDAY
        )
    )
    .setTimeOfDayLowerBound(LocalTime.of(9, 0))
    .setTimeOfDayUpperBound(LocalTime.of(17, 0))
    .build()

// 3. Define the outcome (BLOCK).
val outcome = Outcome.builder()
    .setOutcomeType(BLOCK)
    .build()

// 4. Assemble and apply the rule.
val rule = Rule.builder()
    .setTargets(listOf(target))
    .setPredicate(predicate)
    .setOutcome(outcome)
    .setId("Block Policy")
    .build()

setUucPolicy(policyClient, listOf(rule))

Java

import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.BLOCK;
import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.OS_UPDATE_WITH_API_LEVEL_CHANGE;

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target;
import java.time.DayOfWeek;
import java.time.LocalTime;
import java.util.List;

// 1. Define the target (OS update with API level change).
Target target = Target.builder()
        .setTargetType(OS_UPDATE_WITH_API_LEVEL_CHANGE)
        .build();

// 2. Define the predicate (Monday through Friday, 09:00 to 17:00).
Predicate predicate = Predicate.builder()
        .setDaysOfWeek(
                List.of(
                        DayOfWeek.MONDAY,
                        DayOfWeek.TUESDAY,
                        DayOfWeek.WEDNESDAY,
                        DayOfWeek.THURSDAY,
                        DayOfWeek.FRIDAY
                )
        )
        .setTimeOfDayLowerBound(LocalTime.of(9, 0))
        .setTimeOfDayUpperBound(LocalTime.of(17, 0))
        .build();

// 3. Define the outcome (BLOCK).
Outcome outcome = Outcome.builder()
        .setOutcomeType(BLOCK)
        .build();

// 4. Assemble and apply the rule.
Rule rule = Rule.builder()
        .setTargets(List.of(target))
        .setPredicate(predicate)
        .setOutcome(outcome)
        .setId("Block Policy")
        .build();

setUucPolicy(policyClient, List.of(rule));

अपडेट की उम्र के हिसाब से, ओएस के अपडेट को ज़बरदस्ती लागू करें

यहां दिए गए नियम के तहत, ओएस के मुख्य अपडेट (OS_UPDATE_WITH_API_LEVEL_CHANGE) को सात दिनों के अंदर इंस्टॉल करना ज़रूरी है:

Kotlin

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.FORCE
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.OS_UPDATE_WITH_API_LEVEL_CHANGE
import java.time.Duration

val target = Target.builder()
    .setTargetType(OS_UPDATE_WITH_API_LEVEL_CHANGE)
    .build()

val predicate = Predicate.builder()
    .setUpdateAgeUpperBound(Duration.ofDays(7))
    .build()

val outcome = Outcome.builder()
    .setOutcomeType(FORCE)
    .build()

val rule = Rule.builder()
    .setTargets(listOf(target))
    .setPredicate(predicate)
    .setOutcome(outcome)
    .setId("Force Policy")
    .build()

setUucPolicy(policyClient, listOf(rule))

Java

import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.FORCE;
import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.OS_UPDATE_WITH_API_LEVEL_CHANGE;

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target;
import java.time.Duration;
import java.util.List;

Target target = Target.builder()
        .setTargetType(OS_UPDATE_WITH_API_LEVEL_CHANGE)
        .build();

Predicate predicate = Predicate.builder()
        .setUpdateAgeUpperBound(Duration.ofDays(7))
        .build();

Outcome outcome = Outcome.builder()
        .setOutcomeType(FORCE)
        .build();

Rule rule = Rule.builder()
        .setTargets(List.of(target))
        .setPredicate(predicate)
        .setOutcome(outcome)
        .setId("Force Policy")
        .build();

setUucPolicy(policyClient, List.of(rule));

Google के किसी सिस्टम सर्विस ऐप्लिकेशन के लिए अपडेट ब्लॉक करना

Google की सिस्टम सेवाओं के किसी खास पैकेज को कंट्रोल करने के लिए, टारगेट टाइप को SINGLE_APP पर सेट करें. जैसे, Android System WebView (com.google.android.webview). साथ ही, पैकेज के नाम के साथ SingleApp ऑब्जेक्ट दें:

Kotlin

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.BLOCK
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.SingleApp
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.SINGLE_APP
import java.time.DayOfWeek
import java.time.LocalTime

val target = Target.builder()
    .setTargetType(SINGLE_APP)
    .setSingleApp(
        SingleApp.builder()
            .setPackageName("com.google.android.webview")
            .build()
    )
    .build()

val predicate = Predicate.builder()
    .setDaysOfWeek(
        listOf(
            DayOfWeek.MONDAY,
            DayOfWeek.TUESDAY,
            DayOfWeek.WEDNESDAY,
            DayOfWeek.THURSDAY,
            DayOfWeek.FRIDAY
        )
    )
    .setTimeOfDayLowerBound(LocalTime.of(9, 0))
    .setTimeOfDayUpperBound(LocalTime.of(17, 0))
    .build()

val outcome = Outcome.builder()
    .setOutcomeType(BLOCK)
    .build()

val rule = Rule.builder()
    .setTargets(listOf(target))
    .setPredicate(predicate)
    .setOutcome(outcome)
    .setId("Block Webview Policy")
    .build()

setUucPolicy(policyClient, listOf(rule))

Java

import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.BLOCK;
import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.SINGLE_APP;

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.SingleApp;
import java.time.DayOfWeek;
import java.time.LocalTime;
import java.util.List;

Target target = Target.builder()
        .setTargetType(SINGLE_APP)
        .setSingleApp(
                SingleApp.builder()
                        .setPackageName("com.google.android.webview")
                        .build()
        )
        .build();

Predicate predicate = Predicate.builder()
        .setDaysOfWeek(
                List.of(
                        DayOfWeek.MONDAY,
                        DayOfWeek.TUESDAY,
                        DayOfWeek.WEDNESDAY,
                        DayOfWeek.THURSDAY,
                        DayOfWeek.FRIDAY
                )
        )
        .setTimeOfDayLowerBound(LocalTime.of(9, 0))
        .setTimeOfDayUpperBound(LocalTime.of(17, 0))
        .build();

Outcome outcome = Outcome.builder()
        .setOutcomeType(BLOCK)
        .build();

Rule rule = Rule.builder()
        .setTargets(List.of(target))
        .setPredicate(predicate)
        .setOutcome(outcome)
        .setId("Block Webview Policy")
        .build();

setUucPolicy(policyClient, List.of(rule));

अपडेट के सभी टारगेट के लिए, कई नियमों को एक साथ जोड़ना

नियमों का आकलन क्रम से किया जाता है. इसलिए, एक से ज़्यादा नियमों को जोड़कर, किसी खास समयावधि के दौरान अपडेट ब्लॉक किए जा सकते हैं. जैसे, कारोबार के खुले होने के समय या कैलेंडर की किसी टारगेट तारीख से पहले. साथ ही, उस समयावधि के बाहर अपडेट लागू किए जा सकते हैं.

यहां दिए गए उदाहरण में, कैटगरी के हिसाब से टारगेट करने के चारों विकल्पों (OS_UPDATE_WITH_API_LEVEL_CHANGE, OS_UPDATE_WITHOUT_API_LEVEL_CHANGE, GOOGLE_SYSTEM_SERVICES, और GOOGLE_PLAY_SYSTEM_UPDATE) पर, क्रम में चलने वाले दो नियम लागू किए गए हैं:

  1. कारोबार के खुले होने के समय (सोमवार से शुक्रवार, सुबह 9:00 बजे से शाम 5:00 बजे तक) के दौरान सभी अपडेट ब्लॉक करें.
  2. कारोबार के खुले होने के समय के अलावा, सात दिनों तक उपलब्ध अपडेट को ज़बरदस्ती लागू करें.

Kotlin

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.BLOCK
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.FORCE
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.GOOGLE_PLAY_SYSTEM_UPDATE
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.GOOGLE_SYSTEM_SERVICES
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.OS_UPDATE_WITHOUT_API_LEVEL_CHANGE
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.OS_UPDATE_WITH_API_LEVEL_CHANGE
import java.time.DayOfWeek
import java.time.Duration
import java.time.LocalTime

// 1. Define the targets to reuse across both rules.
val allTargets = listOf(
    Target.builder().setTargetType(OS_UPDATE_WITH_API_LEVEL_CHANGE).build(),
    Target.builder().setTargetType(OS_UPDATE_WITHOUT_API_LEVEL_CHANGE).build(),
    Target.builder().setTargetType(GOOGLE_SYSTEM_SERVICES).build(),
    Target.builder().setTargetType(GOOGLE_PLAY_SYSTEM_UPDATE).build()
)

// 2. Rule 1: Block updates during business hours.
val blockPredicate = Predicate.builder()
    .setDaysOfWeek(
        listOf(
            DayOfWeek.MONDAY,
            DayOfWeek.TUESDAY,
            DayOfWeek.WEDNESDAY,
            DayOfWeek.THURSDAY,
            DayOfWeek.FRIDAY
        )
    )
    .setTimeOfDayLowerBound(LocalTime.of(9, 0))
    .setTimeOfDayUpperBound(LocalTime.of(17, 0))
    .build()

val blockOutcome = Outcome.builder()
    .setOutcomeType(BLOCK)
    .build()

val rule1 = Rule.builder()
    .setTargets(allTargets)
    .setPredicate(blockPredicate)
    .setOutcome(blockOutcome)
    .setId("Block Policy - rule1")
    .build()

// 3. Rule 2: Force updates within 7 days of availability.
val forcePredicate = Predicate.builder()
    .setUpdateAgeUpperBound(Duration.ofDays(7))
    .build()

val forceOutcome = Outcome.builder()
    .setOutcomeType(FORCE)
    .build()

val rule2 = Rule.builder()
    .setTargets(allTargets)
    .setPredicate(forcePredicate)
    .setOutcome(forceOutcome)
    .setId("Force Policy - rule2")
    .build()

setUucPolicy(policyClient, listOf(rule1, rule2))

Java

import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.BLOCK;
import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.FORCE;
import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.GOOGLE_PLAY_SYSTEM_UPDATE;
import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.GOOGLE_SYSTEM_SERVICES;
import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.OS_UPDATE_WITHOUT_API_LEVEL_CHANGE;
import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target.TargetType.OS_UPDATE_WITH_API_LEVEL_CHANGE;

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Target;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalTime;
import java.util.List;

// 1. Define the targets to reuse across both rules.
List allTargets = List.of(
        Target.builder().setTargetType(OS_UPDATE_WITH_API_LEVEL_CHANGE).build(),
        Target.builder().setTargetType(OS_UPDATE_WITHOUT_API_LEVEL_CHANGE).build(),
        Target.builder().setTargetType(GOOGLE_SYSTEM_SERVICES).build(),
        Target.builder().setTargetType(GOOGLE_PLAY_SYSTEM_UPDATE).build()
);

// 2. Rule 1: Block updates during business hours.
Predicate blockPredicate = Predicate.builder()
        .setDaysOfWeek(
                List.of(
                        DayOfWeek.MONDAY,
                        DayOfWeek.TUESDAY,
                        DayOfWeek.WEDNESDAY,
                        DayOfWeek.THURSDAY,
                        DayOfWeek.FRIDAY
                )
        )
        .setTimeOfDayLowerBound(LocalTime.of(9, 0))
        .setTimeOfDayUpperBound(LocalTime.of(17, 0))
        .build();

Outcome blockOutcome = Outcome.builder()
        .setOutcomeType(BLOCK)
        .build();

Rule rule1 = Rule.builder()
        .setTargets(allTargets)
        .setPredicate(blockPredicate)
        .setOutcome(blockOutcome)
        .setId("Block Policy - rule1")
        .build();

// 3. Rule 2: Force updates within 7 days of availability.
Predicate forcePredicate = Predicate.builder()
        .setUpdateAgeUpperBound(Duration.ofDays(7))
        .build();

Outcome forceOutcome = Outcome.builder()
        .setOutcomeType(FORCE)
        .build();

Rule rule2 = Rule.builder()
        .setTargets(allTargets)
        .setPredicate(forcePredicate)
        .setOutcome(forceOutcome)
        .setId("Force Policy - rule2")
        .build();

setUucPolicy(policyClient, List.of(rule1, rule2));

किसी तारीख तक अपडेट पर पाबंदी लगाना

डिवाइस के स्थानीय टाइम ज़ोन में, कैलेंडर की किसी खास तारीख की सीमा के अंदर अपडेट को रोकने या अनुमति देने के लिए, Predicate.Builder पर setDateLowerBound और setDateUpperBound का इस्तेमाल किया जा सकता है:

Kotlin

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.BLOCK
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate
import java.time.LocalDate

val blockUntilDateRule = Rule.builder()
    .setId("block_until_date")
    .setTargets(allTargets)
    .setPredicate(
        Predicate.builder()
            .setDateUpperBound(LocalDate.of(2026, 3, 14))
            .build()
    )
    .setOutcome(Outcome.builder().setOutcomeType(BLOCK).build())
    .build()

setUucPolicy(policyClient, listOf(blockUntilDateRule))

Java

import static com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome.OutcomeType.BLOCK;

import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Outcome;
import com.google.android.managementapi.policy.model.Policy.UnifiedUpdatePolicy.Rule.Predicate;
import java.time.LocalDate;
import java.util.List;

Rule blockUntilDateRule = Rule.builder()
        .setId("block_until_date")
        .setTargets(allTargets)
        .setPredicate(
                Predicate.builder()
                        .setDateUpperBound(LocalDate.of(2026, 3, 14))
                        .build()
        )
        .setOutcome(Outcome.builder().setOutcomeType(BLOCK).build())
        .build();

setUucPolicy(policyClient, List.of(blockUntilDateRule));

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

अगर PolicyClient कॉल पूरा नहीं हो पाता है, तो आपके कस्टम डीपीसी को एक अपवाद मिलता है. यह अपवाद, Kotlin suspend के तरीकों getPolicy और updatePolicy से सीधे तौर पर मिलता है या getPolicyFuture और updatePolicyFuture में ExecutionException की वजह के तौर पर रैप किया जाता है. सामान्य अपवादों में ये शामिल हैं:

  • ApiLevelException: डिवाइस में Android 13 (एपीआई लेवल 33) से पहले का Android वर्शन इस्तेमाल किया जा रहा है.
  • DeviceNotManagedException: डिवाइस को पूरी तरह से मैनेज किए जा रहे डिवाइस (डिवाइस के मालिक) या वर्क प्रोफ़ाइल वाले, कंपनी के मालिकाना हक वाले डिवाइस (सीओपीई) के तौर पर मैनेज नहीं किया जाता है.
  • AndroidDevicePolicyAppNotInstalledException, AndroidDevicePolicyAppDisabledException या AndroidDevicePolicyAppNotUpdatedException: ADP ऐप्लिकेशन इंस्टॉल नहीं है, बंद है या उसका कोई पुराना वर्शन चल रहा है, जो PolicyClient के साथ काम नहीं करता. ADP ऐप्लिकेशन को इंस्टॉल या अपडेट करने के लिए, prepareEnvironment पर कॉल करें.
  • InvalidArgumentException: अनुरोध गलत तरीके से बनाया गया है या इसमें नीति के अमान्य नियम शामिल हैं. उदाहरण के लिए, किसी नियम id को छोड़ना या डुप्लीकेट id का इस्तेमाल करना, दिन के समय की सीमा पर मिनट या सेकंड सेट करना, अपडेट की उम्र की ऐसी अवधि तय करना जो 24 घंटे का गुणज न हो, डुप्लीकेट टारगेट शामिल करना या किसी नियम में साफ़ तौर पर OutcomeType.DEFAULT सेट करना.
  • SecurityException: कॉलिंग ऐप्लिकेशन के पास, डिवाइस से जुड़ी नीति को मैनेज करने की अनुमति नहीं है.
  • TimeoutException (java.util.concurrent.TimeoutException), InternalException या AmapiSdkException की कोई अन्य सबक्लास: एडीपी ऐप्लिकेशन के साथ कम्यूनिकेट करते समय, कुछ समय के लिए आईपीसी या अंदरूनी गड़बड़ी हुई. एक्स्पोनेंशियल बैकऑफ़ रणनीति का इस्तेमाल करके, कॉल को फिर से आज़माएं.

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

कुछ समय के लिए होने वाली गड़बड़ियों (जैसे, TimeoutException या InternalException) के लिए, एक्स्पोनेंशियल बैकऑफ़ के साथ फिर से कोशिश करने की रणनीति लागू करें:

  1. पहली बार अनुरोध पूरा न होने पर, दोबारा कोशिश करने से पहले पांच सेकंड इंतज़ार करें.
  2. हर बार कोशिश करने पर, देरी को तेज़ी से बढ़ाएं (10 सेकंड, 20 सेकंड वगैरह). ऐसा तब तक करें, जब तक कोशिश करने की तय सीमा पूरी न हो जाए.