AMAPI SDK-এর মাধ্যমে ইউনিফায়েড আপডেট কন্ট্রোল কনফিগার করা

এই নির্দেশিকা থেকে জানা যায় যে কীভাবে কোম্পানির মালিকানাধীন ডিভাইসে ইউনিফায়েড আপডেট কন্ট্রোল (UUC) কনফিগার করতে, কাস্টম ডিভাইস নীতি কন্ট্রোলারে (DPC) Android Management API (AMAPI) SDK ব্যবহার করতে হয়।

AMAPI SDK ব্যবহার করে, আপনার কাস্টম DPC সরাসরি ডিভাইসে Android Device Policy (ADP) অ্যাপে UUC নীতি পাঠায়। ADP বর্তমান ডিভাইসের অবস্থার সাথে নীতির নিয়মগুলি মূল্যায়ন করে এবং Google Play এবং OEM OTA ক্লায়েন্টকে নির্দেশ দেয় যে কীভাবে মুলতুবি থাকা আপডেটগুলি পরিচালনা করতে হবে।

শুরু করার আগে, নিয়ম, টার্গেট, প্রেডিকেট ও ফলাফল কীভাবে কাজ করে এবং সব UUC ইন্টিগ্রেশনের ক্ষেত্রে কোন কোন সীমাবদ্ধতা প্রযোজ্য হয় তা জানতে ইউনিফায়েড আপডেট কন্ট্রোল পড়ুন।

পূর্বশর্ত

আপনার কাস্টম DPC-তে UUC ইন্টিগ্রেট করার আগে, নিম্নলিখিত প্রয়োজনীয়তাগুলি যাচাই করুন:

আপনার কাস্টম DPC-তে AMAPI SDK-এর সাথে ইন্টিগ্রেট করুন

ডিভাইসে UUC নীতি কনফিগার করতে, আপনার কাস্টম DPC-কে AMAPI SDK-এর সাথে ইন্টিগ্রেট করতে হবে। লাইব্রেরি যোগ করা এবং আপনার অ্যাপের ম্যানিফেস্ট কনফিগার করার নির্দেশাবলীর জন্য, AMAPI SDK ইন্টিগ্রেশন গাইড দেখুন।

ইউনিফায়েড আপডেট কন্ট্রোল কনফিগার করার ধাপ

আপনার কাস্টম DPC থেকে UUC নীতি কনফিগার করতে, ADP-তে নীতি সংক্রান্ত অনুরোধ পাঠানোর আগে অন-ডিভাইস ক্লায়েন্ট এনভায়রনমেন্ট প্রস্তুত এবং আপ-টু-ডেট আছে কিনা তা নিশ্চিত করুন:

  1. ক্লায়েন্ট এনভায়রনমেন্ট যাচাই করা
  2. ক্লায়েন্ট এনভায়রনমেন্ট তৈরি করা
  3. আপডেট নীতি সেট, ফিরিয়ে আনা ও মুছে ফেলা

ক্লায়েন্ট এনভায়রনমেন্ট যাচাই করুন

নিচের উদাহরণে দেখানো হয়েছে যে কীভাবে Role.RoleType.DEVICE_POLICY_CONTROLLER-এর সাথে getEnvironment (Kotlin-এ) বা getEnvironmentAsync (Java-তে) কল করে ADP অ্যাপের স্ট্যাটাস চেক করতে হয়। যদি এনভায়রনমেন্ট READY ও UP_TO_DATE হয়, তাহলে আপনার কাস্টম DPC, PolicyClient ব্যবহার করে UUC নীতি কনফিগার করার জন্য এগিয়ে যেতে পারে। অন্যথায়, 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 সহ কাস্টম DPC থেকে কল করা হলে এবং আপনার DPC-এর DeviceAdminReceiver কম্পোনেন্টের নাম setAdmin()-এ পাস করা হলে, prepareEnvironment ADP অ্যাপ (যদি আগে থেকে ইনস্টল করা না থাকে) সাইলেন্টলি ইনস্টল করে এবং ব্যবহারকারীর ইন্টার‍্যাকশন ছাড়াই ADP অ্যাপ ও Google Play Store আপডেট করে। কাস্টম DPC ফ্লোতে এনভায়রনমেন্ট প্রস্তুত করা সম্পর্কে আরও তথ্যের জন্য, এনভায়রনমেন্ট প্রস্তুত করা এবং ব্যবহারকারী এনরোলমেন্ট দেখুন।

-এ ফলাফল দেখায়

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)-এর মাধ্যমে তৈরি) ব্যবহার করে আপনার UnifiedUpdatePolicy নিয়ম সহ Policy প্রয়োগ করুন, অ্যাক্টিভ নীতি পরীক্ষা করুন অথবা ডিভাইস থেকে UUC নীতি মুছে দিন।

PolicyClient ব্যবহার সংক্রান্ত সাজেশন

PolicyClient ইনস্ট্যান্স তৈরি করলে, ADP অ্যাপের সাথে একটি কমিউনিকেশন চ্যানেল তৈরি হয়। পারফর্ম্যান্স অপ্টিমাইজ করতে, আমরা PolicyClientFactory.create() ব্যবহার করে PolicyClient-এর একটি ইনস্ট্যান্স তৈরি করার এবং আপনার অ্যাপ্লিকেশন জুড়ে আবার ব্যবহার করার জন্য এটি ক্যাশে করার সাজেশন দিই। অন্য একটি PolicyClient ইনস্ট্যান্স অ্যাক্টিভ থাকাকালীন নতুন ইনস্ট্যান্স তৈরি করা এড়িয়ে চলুন, কারণ এটি করলে আগে থেকে থাকা কমিউনিকেশন চ্যানেল বন্ধ হয়ে যেতে পারে, যার ফলে ওভারহেড এবং রিসোর্স লিক হতে পারে।

আপডেট নীতি সেট করুন

UUC নিয়ম প্রয়োগ করতে, আপনার Rule অবজেক্টের তালিকা সহ একটি Policy.UnifiedUpdatePolicy তৈরি করুন, এটি 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);
    }
}

অ্যাক্টিভ আপডেট নীতি ফিরিয়ে আনুন

ডিভাইসে অ্যাক্টিভ UUC নীতি পরীক্ষা করতে, একটি GetPolicyRequest তৈরি করুন এবং getPolicy (Kotlin-এ) বা getPolicyFuture (Java-তে) কল করুন। UUC নীতি কনফিগার করা আছে কিনা তা চেক করতে, ফেরত আসা 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 অগ্রাধিকার

কাস্টম DPC-তে, Android কম্প্যাটিবিলিটি ডেফিনেশন ডকুমেন্ট (CDD) অনুযায়ী ডিভাইসে DevicePolicyManager.setSystemUpdatePolicy-এর মাধ্যমে সেট করা AOSP SystemUpdatePolicy মেনে চলতে হবে।

এর ফলে, ডিভাইসে AOSP SystemUpdatePolicy অ্যাক্টিভ আছে কিনা তার উপর OEM OTA আপডেট নির্ভর করে:

  • UUC নীতি এবং AOSP SystemUpdatePolicy দুটিই সেট করা আছে: OEM OTA আপডেটের জন্য AOSP SystemUpdatePolicy অগ্রাধিকার পায় এবং UUC টার্গেট OS_UPDATE_WITH_API_LEVEL_CHANGE এবং OS_UPDATE_WITHOUT_API_LEVEL_CHANGE উপেক্ষা করা হয়। UUC-এর মাধ্যমে OEM OTA আপডেট ম্যানেজ করতে চাইলে, আপনার কাস্টম DPC-তে AOSP SystemUpdatePolicy মুছে দিন।
  • শুধুমাত্র UUC নীতি সেট করা আছে (AOSP SystemUpdatePolicy মুছে দেওয়া হয়েছে): OEM OTA এজেন্ট কাজ করে এমন ডিভাইসে OEM OTA আপডেটের জন্য UUC নীতি প্রয়োগ করে।
  • OEM OTA আপডেটের জন্য এখনও UUC কাজ করে না এমন ডিভাইস: যেসব ডিভাইসে OEM OTA কাজ করার জন্য Android 17 (API লেভেল ৩৭) প্রয়োজন, সেখানে আপনি UUC ব্যবহার করে Google Play সিস্টেম আপডেট (GOOGLE_PLAY_SYSTEM_UPDATE) এবং Google সিস্টেম পরিষেবা (GOOGLE_SYSTEM_SERVICES এবং SINGLE_APP) নিয়ন্ত্রণ করতে পারবেন এবং OEM OTA আপডেটের জন্য AOSP 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-তে কীভাবে UUC নিয়ম তৈরি করতে হয় এবং আপডেট নীতি সেট, ফিরিয়ে আনা ও মুছে ফেলা-তে উল্লেখ করা setUucPolicy হেল্পার ব্যবহার করে সেগুলি প্রয়োগ করতে হয় তা নিম্নলিখিত উদাহরণ থেকে জানতে পারবেন। প্রতিটি ফিল্ডের অর্থ জানতে, UUC নীতি বুঝুন দেখুন। একই পরিস্থিতি JSON হিসেবে ইউনিফায়েড আপডেট কন্ট্রোল-এ উপলভ্য।

কর্মসময়ের মধ্যে OS-এর গুরুত্বপূর্ণ আপডেট ব্লক করুন

নিম্নলিখিত নিয়মটি সোমবার থেকে শুক্রবার সকাল ৯টা থেকে বিকাল ৫টা পর্যন্ত OS-এর প্রধান আপডেট (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 আপডেট করতে বাধ্য করুন

নিম্নলিখিত নিয়মটি OS-এর প্রধান আপডেট (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 সিস্টেম পরিষেবার অংশ হিসেবে কোনও নির্দিষ্ট প্যাকেজ কন্ট্রোল করতে—যেমন Android System WebView (com.google.android.webview)—টার্গেট টাইপ SINGLE_APP হিসেবে সেট করুন এবং প্যাকেজের নাম সহ 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. কর্মসময়ের (সোমবার–শুক্রবার, ০৯:০০ থেকে ১৭:০০) মধ্যে সব আপডেট ব্লক করুন।
  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 কল ব্যর্থ হলে, আপনার কাস্টম DPC একটি ব্যতিক্রম (সরাসরি Kotlin suspend পদ্ধতি getPolicy এবং updatePolicy দ্বারা থ্রো করা হয়, অথবা getPolicyFuture এবং updatePolicyFuture-এ ExecutionException-এর কারণ হিসেবে র‍্যাপ করা হয়) পায়। সাধারণ ব্যতিক্রমের মধ্যে রয়েছে:

  • ApiLevelException: ডিভাইসটি Android 13 (API লেভেল 33)-এর আগের কোনও Android ভার্সনে চলে।
  • DeviceNotManagedException: ডিভাইসটি সম্পূর্ণ ম্যানেজ করা ডিভাইস (ডিভাইসের মালিক) বা অফিস প্রোফাইল (COPE) সহ কোম্পানির মালিকানাধীন ডিভাইস হিসেবে ম্যানেজ করা হয় না।
  • AndroidDevicePolicyAppNotInstalledException, AndroidDevicePolicyAppDisabledException, অথবা AndroidDevicePolicyAppNotUpdatedException: ADP অ্যাপ ইনস্টল করা নেই, বন্ধ করা আছে অথবা পুরনো ভার্সন চলছে যা PolicyClient-এ কাজ করে না। ADP অ্যাপ ইনস্টল বা আপডেট করতে prepareEnvironment নম্বরে কল করুন।
  • InvalidArgumentException: অনুরোধটি ভুলভাবে ফর্ম্যাট করা হয়েছে অথবা এতে ভুল নীতি সংক্রান্ত নিয়ম আছে (যেমন, কোনও নিয়ম id বাদ দেওয়া অথবা ডুপ্লিকেট id ব্যবহার করা, দিনের-সময় সংক্রান্ত সীমাতে মিনিট বা সেকেন্ড সেট করা, আপডেট করার বয়স সংক্রান্ত সময়সীমা উল্লেখ করা যা ২৪ ঘণ্টার গুণিতক নয়, ডুপ্লিকেট টার্গেট অন্তর্ভুক্ত করা অথবা কোনও নিয়মে স্পষ্টভাবে OutcomeType.DEFAULT সেট করা)।
  • SecurityException: কলিং অ্যাপের কাছে ডিভাইস নীতি ম্যানেজ করার অনুমতি নেই।
  • TimeoutException (java.util.concurrent.TimeoutException), InternalException, অথবা AmapiSdkException-এর অন্য সাবক্লাস: ADP অ্যাপের সাথে যোগাযোগ করার সময় একটি ক্ষণস্থায়ী IPC বা ইন্টার্নাল সমস্যা হয়েছে। এক্সপোনেনশিয়াল ব্যাকঅফ স্ট্র্যাটেজি ব্যবহার করে কলটি আবার করার চেষ্টা করুন।

স্ট্র্যাটেজি আবার চেষ্টা করুন

ক্ষণস্থায়ী অবস্থার কারণে হওয়া ব্যতিক্রমের জন্য (যেমন TimeoutException বা InternalException), এক্সপোনেনশিয়াল ব্যাক-অফ সহ আবার চেষ্টা করার স্ট্র্যাটেজি প্রয়োগ করুন:

  1. প্রথমবার ব্যর্থ হওয়ার পরে, আবার চেষ্টা করার আগে ৫ সেকেন্ড অপেক্ষা করুন।
  2. প্রতিটি পরবর্তী প্রচেষ্টায় (১০ সেকেন্ড, ২০ সেকেন্ড, ইত্যাদি) সর্বাধিক সংখ্যক প্রচেষ্টা পর্যন্ত বিলম্বের সময় বাড়ান।