AMAPI SDK ile Birleştirilmiş Güncelleme Denetimleri'ni yapılandırma

Bu kılavuzda, şirkete ait cihazlarda Birleştirilmiş Güncelleme Denetimleri'ni (UUC) yapılandırmak için özel bir Cihaz Politikası Denetleyicisi'nde (DPC) Android Management API (AMAPI) SDK'sının nasıl kullanılacağı açıklanmaktadır.

Özel DPC'niz, AMAPI SDK'yı kullanarak doğrudan cihazdaki Android Device Policy (ADP) uygulamasına bir UUC politikası gönderir. ADP, politika kurallarını mevcut cihaz durumuna göre değerlendirir ve Google Play ile OEM OTA istemcisine bekleyen güncellemelerin nasıl işleneceğini bildirir.

Başlamadan önce, kuralların, hedeflerin, yüklemlerin ve sonuçların nasıl çalıştığını ve tüm UUC entegrasyonları için geçerli olan sınırlamaları öğrenmek üzere Birleştirilmiş Güncelleme Kontrolleri başlıklı makaleyi okuyun.

Ön koşullar

UUC'yi özel DPC'nize entegre etmeden önce aşağıdaki şartları karşıladığınızdan emin olun:

  • Cihaz şirkete aittir ve tümüyle yönetilen cihaz olarak veya şirkete ait bir cihazda iş profili ile yapılandırılmıştır.
  • Özel DPC'niz AMAPI SDK ile entegre edilmiştir.
  • Cihaz, Google Play EMM API kullanılarak kaydedilmiştir.
  • Cihaz, yönetim modu ve kontrol etmek istediğiniz her güncelleme hedefi için minimum sürüm gereksinimlerini karşılıyor:
    • Tümüyle yönetilen (Cihaz Sahibi) cihazlar: Android 13 (API düzeyi 33) veya sonraki sürümler.
    • İş profili bulunan, şirkete ait cihazlar (COPE): Android 15 (API düzeyi 35) veya sonraki sürümler.
  • İş profili olan, şirkete ait cihazlarda (COPE):
    • Özel DPC'niz, iş profilinden (özel DPC'nin profil sahibi olduğu) EnvironmentClient ve PolicyClient yöntemlerini çağırmalıdır.
    • UUC'nin Google Play güncellemeleriyle ilgili politikaları (GOOGLE_SYSTEM_SERVICES, SINGLE_APP ve GOOGLE_PLAY_SYSTEM_UPDATE) uygulayabilmesi için iş profilinde bir Managed Google Play hesabı (Google Play EMM API aracılığıyla temel hazırlığı yapılmış) bulunmalıdır.

Özel DPC'nizde AMAPI SDK'yı entegre etme

Bir cihazda UUC politikası yapılandırmak için özel DPC'nizin AMAPI SDK'sı ile entegre edilmesi gerekir. Kitaplığı ekleme ve uygulamanızın manifest dosyasını yapılandırma talimatları için AMAPI SDK entegrasyon kılavuzuna bakın.

Birleştirilmiş güncelleme kontrollerini yapılandırma adımları

Özel DPC'nizden UUC politikalarını yapılandırmak için ADP'ye politika istekleri göndermeden önce cihaz üzerindeki istemci ortamının hazır ve güncel olduğundan emin olun:

  1. İstemci ortamını doğrulama
  2. İstemci ortamını hazırlama
  3. Güncelleme politikasını ayarlama, alma ve temizleme

Müşteri ortamını doğrulama

Aşağıdaki örnekte, ADP uygulamasının durumunu incelemek için Role.RoleType.DEVICE_POLICY_CONTROLLER ile getEnvironment (Kotlin'de) veya getEnvironmentAsync (Java'da) yönteminin nasıl çağrılacağı gösterilmektedir. Ortam READY ve UP_TO_DATE ise özel DPC'niz PolicyClient kullanarak UUC politikalarını yapılandırmaya devam edebilir. Aksi takdirde, ADP uygulamasını yüklemek veya güncellemek için prepareEnvironment komutunu çağırın (İstemci ortamını hazırlama bölümüne bakın).

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

İstemci ortamını hazırlama

Cihazdaki ortam hazır veya güncel değilse PolicyClient kullanmadan önce prepareEnvironment yöntemini çağırın.

Role.RoleType.DEVICE_POLICY_CONTROLLER ile özel bir DPC'den çağrıldığında ve DPC'nizin DeviceAdminReceiver bileşen adı setAdmin() öğesine iletildiğinde prepareEnvironment, ADP uygulamasını sessizce yükler (henüz yüklenmemişse) ve ADP uygulamasını ve Google Play Store'u kullanıcı etkileşimi olmadan günceller. Özel DPC akışlarında ortam hazırlığı hakkında daha fazla bilgi için Ortam hazırlığı ve kullanıcı kaydı başlıklı makaleyi inceleyin.

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

Güncelleme politikasını ayarlama, alma ve temizleme

Ortam hazır olduktan sonra PolicyClient (PolicyClientFactory.create(context) ile oluşturulur) kullanarak UnifiedUpdatePolicy kurallarınızı içeren bir Policy uygulayın, etkin politikayı inceleyin veya UUC politikasını cihazdan temizleyin.

PolicyClient kullanım önerisi

PolicyClient örneği oluşturulduğunda ADP uygulamasıyla bir iletişim kanalı kurulur. Performansı optimize etmek için PolicyClientFactory.create() kullanarak tek bir PolicyClient örneği oluşturmanızı ve uygulamanızda yeniden kullanmak üzere önbelleğe almanızı öneririz. Başka bir PolicyClient örneği etkinken yeni bir örnek oluşturmaktan kaçının. Aksi takdirde mevcut iletişim kanalı kapanmaya zorlanabilir. Bu da ek yük oluşturur ve kaynak sızıntılarına yol açabilir.

Güncelleme politikasını ayarlama

UUC kurallarını uygulamak için Rule nesnelerinizin listesini içeren bir Policy.UnifiedUpdatePolicy oluşturun, bunu bir UpdatePolicyRequest içindeki Policy öğesine ekleyin ve updatePolicy (Kotlin'de) veya updatePolicyFuture (Java'da) yöntemini çağırın:

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

Etkin güncelleme politikasını alma

Cihazdaki etkin UUC politikasını incelemek için bir GetPolicyRequest oluşturun ve getPolicy (Kotlin'de) veya getPolicyFuture (Java'da) yöntemini çağırın. Döndürülen Policy üzerinde hasUnifiedUpdatePolicy() kullanarak bir UUC politikasının yapılandırılıp yapılandırılmadığını kontrol edin:

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

Güncelleme politikasını temizleme

Policy üzerindeki diğer alanları temizlemeden UnifiedUpdatePolicy öğesini cihazdan kaldırmak için getPolicy kullanarak mevcut Policy öğesini alın, currentPolicy.toBuilder().clearUnifiedUpdatePolicy().build() öğesini çağırın ve güncellenmiş Policy öğesini uygulayın:

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 önceliği

Özel bir DPC'de Android Uyumluluk Tanımlama Belgesi (CDD), cihazların DevicePolicyManager.setSystemUpdatePolicy aracılığıyla ayarlanan AOSP SystemUpdatePolicy değerine uymasını gerektirir.

Bu nedenle, OEM OTA güncelleme davranışı, cihazda bir AOSP SystemUpdatePolicy etkin olup olmadığına bağlıdır:

  • Hem UUC politikası hem de AOSP SystemUpdatePolicy ayarlanmışsa: OEM OTA güncellemeleri için AOSP SystemUpdatePolicy öncelikli olur ve UUC hedefleri OS_UPDATE_WITH_API_LEVEL_CHANGE ile OS_UPDATE_WITHOUT_API_LEVEL_CHANGE yoksayılır. UUC'nin OEM OTA güncellemelerini yönetmesini istiyorsanız özel DPC'nizdeki AOSP'yi SystemUpdatePolicy temizleyin.
  • Yalnızca UUC politikası ayarlanmışsa (AOSP SystemUpdatePolicy temizlenmişse): OEM OTA aracısı, desteklenen cihazlarda OEM OTA güncellemeleri için UUC politikasını uygular. Ancak OEM'e özel bir güncelleme yönetim hizmeti (ör. kurumsal FOTA çözümü) etkinse ve cihazda öncelikliyse bu durum geçerli değildir.
  • OEM OTA güncellemeleri için henüz UUC'yi desteklemeyen cihazlar: OEM OTA desteği için Android 17 (API düzeyi 37) gereken cihazlarda, OEM OTA güncellemeleri için AOSP SystemUpdatePolicy'yi kullanmaya devam ederken Google Play sistem güncellemelerini (GOOGLE_PLAY_SYSTEM_UPDATE) ve Google sistem hizmetlerini (GOOGLE_SYSTEM_SERVICES ve SINGLE_APP) kontrol etmek için UUC'yi kullanabilirsiniz.

Cihazda AOSP SystemUpdatePolicy'nin etkin olup olmadığını kontrol etmek için DevicePolicyManager kullanabilirsiniz:

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

Politika yapılandırma örnekleri

Aşağıdaki örneklerde, Kotlin ve Java'da UUC kurallarının nasıl oluşturulacağı ve Güncelleme politikasını ayarlama, alma ve temizleme bölümünde tanımlanan setUucPolicy yardımcı programı kullanılarak nasıl uygulanacağı gösterilmektedir. Her alanın anlamı için UUC politikalarını anlama başlıklı makaleyi inceleyin. Aynı senaryolar, Birleştirilmiş Güncelleme Kontrolleri'nde JSON olarak da mevcuttur.

Çalışma saatleri içinde önemli OS güncellemelerini engelleme

Aşağıdaki kural, pazartesiden cumaya 09:00-17:00 saatleri arasında önemli OS güncellemelerini (OS_UPDATE_WITH_API_LEVEL_CHANGE) engeller:

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));

İşletim sistemi güncellemelerini güncelleme yaşına göre zorunlu kılma

Aşağıdaki kural, güncelleme yaşının üst sınırı 7 gün olan önemli işletim sistemi güncellemelerini (OS_UPDATE_WITH_API_LEVEL_CHANGE) zorunlu kılar:

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));

Tek bir Google sistem hizmeti uygulaması için güncellemeleri engelleme

Google sistem hizmetlerinin parçası olan belirli bir paketi (ör. Android System WebView (com.google.android.webview)) kontrol etmek için hedef türünü SINGLE_APP olarak ayarlayın ve paket adını içeren bir SingleApp nesnesi sağlayın:

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));

Tüm güncelleme hedeflerinde birden fazla kuralı birleştirme

Kurallar sırayla değerlendirildiğinden, belirli zaman aralıklarında (ör. çalışma saatleri veya hedef takvim tarihinden önce) güncellemeleri engellemek ve bu zaman aralıklarının dışında güncellemeleri zorunlu kılmak için birden fazla kuralı birleştirebilirsiniz.

Aşağıdaki örnekte, dört kategori hedefinin (OS_UPDATE_WITH_API_LEVEL_CHANGE, OS_UPDATE_WITHOUT_API_LEVEL_CHANGE, GOOGLE_SYSTEM_SERVICES ve GOOGLE_PLAY_SYSTEM_UPDATE) tümüne iki sıralı kural uygulanmaktadır:

  1. Çalışma saatleri içinde (pazartesi-cuma, 09:00-17:00) tüm güncellemeleri engelleme
  2. Çalışma saatleri dışında, 7 güne kadar kullanılabilir olan güncellemeleri zorunlu kıl.

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));

Güncellemeleri belirli bir takvim tarihine kadar kısıtlama

Cihazın yerel saat diliminde belirli bir takvim tarihi aralığındaki güncellemeleri kısıtlamak veya bunlara izin vermek için Predicate.Builder cihazlarda setDateLowerBound ve setDateUpperBound politikalarını kullanabilirsiniz:

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));

Hataları işleme

Bir PolicyClient çağrısı başarısız olursa özel DPC'niz bir istisna alır (doğrudan Kotlin suspend yöntemleri getPolicy ve updatePolicy tarafından oluşturulur veya getPolicyFuture ve updatePolicyFuture içinde ExecutionException nedeni olarak sarmalanır). Yaygın istisnalar şunlardır:

  • ApiLevelException: Cihazda Android 13'ten (API düzeyi 33) daha eski bir Android sürümü yüklü.
  • DeviceNotManagedException: Cihaz, tümüyle yönetilen bir cihaz (Cihaz Sahibi) veya iş profili bulunan, şirkete ait bir cihaz (COPE) olarak yönetilmiyor.
  • AndroidDevicePolicyAppNotInstalledException, AndroidDevicePolicyAppDisabledException veya AndroidDevicePolicyAppNotUpdatedException: ADP uygulaması yüklü değil, devre dışı bırakılmış veya PolicyClient özelliğini desteklemeyen eski bir sürümü çalıştırıyor. ADP uygulamasını yüklemek veya güncellemek için prepareEnvironment numaralı telefonu arayın.
  • InvalidArgumentException: İstek hatalı biçimlendirilmiş veya geçersiz politika kuralları içeriyor (ör. bir kuralı id atlama veya yinelenen bir id kullanma, günün saati sınırında dakika veya saniye ayarlama, 24 saatin katı olmayan bir güncelleme yaşı süresi belirtme, yinelenen hedefler ekleme veya bir kuralda açıkça OutcomeType.DEFAULT ayarlama).
  • SecurityException: Çağrı yapan uygulamanın cihaz politikasını yönetme yetkisi yok.
  • TimeoutException (java.util.concurrent.TimeoutException), InternalException veya AmapiSdkException sınıfının başka bir alt sınıfı: ADP uygulamasıyla iletişim kurulurken geçici bir IPC veya dahili hata oluştu. Eksponansiyel geri yükleme stratejisi kullanarak çağrıyı yeniden deneyin.

Yeniden deneme stratejileri

Geçici bir durumun (ör. TimeoutException veya InternalException) neden olduğu istisnalar için eksponansiyel geri yükleme ile yeniden deneme stratejisi uygulayın:

  1. İlk başarısız denemeden sonra tekrar denemeden önce 5 saniye bekleyin.
  2. Maksimum deneme sayısına ulaşılana kadar her denemede gecikmeyi katlanarak artırın (10 saniye, 20 saniye vb.).