Bütünlük kararları

Bu sayfada, döndürülen bütünlük kararının nasıl yorumlanacağı ve bu kararla nasıl çalışılacağı açıklanmaktadır. İster standart ister klasik bir API isteğinde bulunun, bütünlük kararı benzer içerikle aynı biçimde döndürülür. Bütünlük kararı; cihazların, uygulamaların ve hesapların geçerliliği hakkında bilgi iletir. Uygulamanızın sunucusu, uygulamanızdaki belirli bir işlem veya isteği en iyi şekilde nasıl gerçekleştireceğinizi belirlemek için bu yükü, şifresi çözülmüş ve doğrulanmış bir kararda kullanabilir.

Entegrasyon kararı biçimi döndürüldü

Yük, düz metin JSON biçimindedir ve geliştirici tarafından sağlanan bilgilerin yanı sıra bütünlük sinyallerini içerir.

Genel yük yapısı şu şekildedir:

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
  environmentDetails: { ... }
}

Her bir entegrasyon kararını kontrol etmeden önce requestDetails alanındaki değerlerin orijinal isteğin değerleriyle eşleşip eşleşmediğini kontrol etmeniz gerekir. Aşağıdaki bölümlerde her alan daha ayrıntılı olarak açıklanmaktadır.

İstek ayrıntıları alanı

requestDetails alanı, standart istekler için requestHash içinde geliştirici tarafından sağlanan bilgiler ve klasik istekler için nonce dahil olmak üzere istekle ilgili bilgileri içerir.

Standart API istekleri için:

requestDetails: {
  // Application package name this attestation was requested for.
  // Note that this field might be spoofed in the middle of the request.
  requestPackageName: "com.package.name"
  // Request hash provided by the developer.
  requestHash: "aGVsbG8gd29scmQgdGhlcmU"
  // The timestamp in milliseconds when the integrity token
  // was prepared (computed on the server).
  timestampMillis: "1675655009345"
}

Bu değerler, orijinal isteğin değerleriyle eşleşmelidir. Bu nedenle, aşağıdaki kod snippet'inde gösterildiği gibi requestPackageName ve requestHash değerlerinin orijinal istekte gönderilenle eşleştiğinden emin olarak JSON yükünün requestDetails kısmını doğrulayın:

Kotlin

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val requestHash = requestDetails.getString("requestHash")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Java

RequestDetails requestDetails =
    decodeIntegrityTokenResponse
    .getTokenPayloadExternal()
    .getRequestDetails();
String requestPackageName = requestDetails.getRequestPackageName();
String requestHash = requestDetails.getRequestHash();
long timestampMillis = requestDetails.getTimestampMillis();
long currentTimestampMillis = ...;

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request.
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Klasik API istekleri için:

requestDetails: {
  // Application package name this attestation was requested for.
  // Note that this field might be spoofed in the middle of the
  // request.
  requestPackageName: "com.package.name"
  // base64-encoded URL-safe no-wrap nonce provided by the developer.
  nonce: "aGVsbG8gd29scmQgdGhlcmU"
  // The timestamp in milliseconds when the request was made
  // (computed on the server).
  timestampMillis: "1617893780"
}

Bu değerler, orijinal isteğin değerleriyle eşleşmelidir. Bu nedenle, aşağıdaki kod snippet'inde gösterildiği gibi requestPackageName ve nonce değerlerinin orijinal istekte gönderilenle eşleştiğinden emin olarak JSON yükünün requestDetails kısmını doğrulayın:

Kotlin

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val nonce = requestDetails.getString("nonce")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Java

JSONObject requestDetails =
    new JSONObject(payload).getJSONObject("requestDetails");
String requestPackageName = requestDetails.getString("requestPackageName");
String nonce = requestDetails.getString("nonce");
long timestampMillis = requestDetails.getLong("timestampMillis");
long currentTimestampMillis = ...;

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Uygulama bütünlüğü alanı

appIntegrity alanı, paketle ilgili bilgileri içerir.

appIntegrity: {
  // PLAY_RECOGNIZED, UNRECOGNIZED_VERSION, or UNEVALUATED.
  appRecognitionVerdict: "PLAY_RECOGNIZED"
  // The package name of the app.
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  packageName: "com.package.name"
  // The sha256 digest of app certificates (base64-encoded URL-safe).
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  certificateSha256Digest: ["6a6a1474b5cbbb2b1aa57e0bc3"]
  // The version of the app.
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  versionCode: "42"
}

appRecognitionVerdict aşağıdaki değerlere sahip olabilir:

PLAY_RECOGNIZED
Uygulama ve sertifika, Google Play tarafından dağıtılan sürümlerle eşleşiyor.
UNRECOGNIZED_VERSION
Sertifika veya paket adı Google Play kayıtlarıyla eşleşmiyor.
UNEVALUATED
Uygulama bütünlüğü değerlendirilmedi. Gerekli bir şart karşılanmamıştır (örneğin, cihaz yeterince güvenilir değildir).

Jetonun sizin tarafınızdan oluşturulan bir uygulama tarafından oluşturulduğundan emin olmak için aşağıdaki kod snippet'inde gösterildiği gibi uygulama bütünlüğünün beklendiği gibi olduğunu doğrulayın:

Kotlin

val appIntegrity = JSONObject(payload).getJSONObject("appIntegrity")
val appRecognitionVerdict = appIntegrity.getString("appRecognitionVerdict")

if (appRecognitionVerdict == "PLAY_RECOGNIZED") {
    // Looks good!
}

Java

JSONObject appIntegrity =
    new JSONObject(payload).getJSONObject("appIntegrity");
String appRecognitionVerdict =
    appIntegrity.getString("appRecognitionVerdict");

if (appRecognitionVerdict.equals("PLAY_RECOGNIZED")) {
    // Looks good!
}

Uygulama paketi adını, uygulama sürümünü ve uygulama sertifikalarını manuel olarak da kontrol edebilirsiniz.

Cihaz bütünlüğü alanı

deviceIntegrity alanı, cihazın uygulama bütünlüğünü ne kadar iyi zorunlu kılabileceğini temsil eden bir veya daha fazla etikete sahip tek bir değer (deviceRecognitionVerdict) içerebilir. Cihaz, hiçbir etiketin kriterlerini karşılamıyorsa deviceIntegrity alanı boş olur.

deviceIntegrity: {
  // "MEETS_DEVICE_INTEGRITY" is one of several possible values.
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
}

Varsayılan olarak deviceRecognitionVerdict aşağıdakileri içerebilir:

MEETS_DEVICE_INTEGRITY
Uygulama, Google Play Hizmetleri'nin yüklü olduğu Android destekli bir cihazda çalışıyor. Cihaz, sistem bütünlüğü kontrollerini geçer ve Android uyumluluk şartlarını karşılar.
Boş (boş değer)
Uygulama, saldırı belirtileri (ör. API kancalama) veya sistemde güvenlik ihlali (rootlanma gibi) belirtileri olan bir cihazda çalışıyor ya da uygulama fiziksel bir cihazda çalışmıyor (ör. Google Play bütünlük kontrollerini geçemeyen bir emülatörde).

Jetonun güvenilir bir cihazdan geldiğinden emin olmak için deviceRecognitionVerdict öğesinin aşağıdaki kod snippet'inde gösterildiği gibi beklendiği gibi olduğunu doğrulayın:

Kotlin

val deviceIntegrity =
    JSONObject(payload).getJSONObject("deviceIntegrity")
val deviceRecognitionVerdict =
    if (deviceIntegrity.has("deviceRecognitionVerdict")) {
        deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    } else {
        ""
    }

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

Java

JSONObject deviceIntegrity =
    new JSONObject(payload).getJSONObject("deviceIntegrity");
String deviceRecognitionVerdict =
    deviceIntegrity.has("deviceRecognitionVerdict")
    ? deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    : "";

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

Test cihazınızın cihaz bütünlüğünü karşılamasıyla ilgili sorunlar yaşıyorsanız fabrika ROM'unun yüklü olduğundan (örneğin, cihazı sıfırlayarak) ve bootloader'ın kilitli olduğundan emin olun. Play Console'da Play Integrity API testlerini de oluşturabilirsiniz.

Koşullu cihaz etiketleri

Uygulamanız PC Üzerinde Google Play Games'de yayınlanıyorsa deviceRecognitionVerdict üzerinde aşağıdaki etiket de bulunabilir:

MEETS_VIRTUAL_INTEGRITY
Uygulama, Google Play Hizmetleri ile Android destekli bir emülatörde çalışıyor. Emülatör, sistem bütünlüğü kontrollerini geçer ve temel Android uyumluluk gereksinimlerini karşılar.

İsteğe bağlı cihaz bilgileri

Entegrasyon kararında ek etiketler almayı etkinleştirirseniz deviceRecognitionVerdict aşağıdaki ek etiketleri içerebilir:

MEETS_BASIC_INTEGRITY
Uygulama, temel sistem bütünlüğü kontrollerini geçen bir cihazda çalışıyor. Cihaz, Android uyumluluk koşullarını karşılamıyor olabilir ve Google Play hizmetlerini çalıştırmak üzere onaylanmayabilir. Örneğin, cihaz Android'in tanınmayan bir sürümünü çalıştırıyor, kilidi açılmış bir bootloader içeriyor veya üretici tarafından onaylanmamış olabilir.
MEETS_STRONG_INTEGRITY
Uygulama, Google Play Hizmetleri'nin bulunduğu Android destekli bir cihazda çalışmaktadır ve sistem bütünlüğü, donanım bütünlüğü destekli kanıtı gibi güçlü bir sistem bütünlüğü garantisine sahiptir. Cihaz, sistem bütünlüğü kontrollerini geçer ve Android uyumluluk koşullarını karşılar.

Etiketin ölçütlerinden her biri karşılanırsa tek bir cihaz, cihaz bütünlüğü kararında birden fazla cihaz etiketi döndürür.

Son cihaz etkinliği (Beta)

Son cihaz etkinliğini de etkinleştirebilirsiniz. Bu etkinlik, uygulamanızın son bir saat içinde belirli bir cihazda kaç kez bütünlük jetonu istediğini belirtir. Uygulamanızı, etkin bir saldırının göstergesi olabilecek beklenmedik, hiperaktif cihazlara karşı korumak için son cihaz etkinliğini kullanabilirsiniz. Uygulamanızın her saat kaç kez bütünlük jetonu istemesini beklediğinize bağlı olarak son cihaz etkinliği düzeylerine ne kadar güveneceğinize karar verebilirsiniz.

recentDeviceActivity verisini almayı etkinleştirirseniz deviceIntegrity alanında iki değer bulunur:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  recentDeviceActivity: {
    // "LEVEL_2" is one of several possible values.
    deviceActivityLevel: "LEVEL_2"
  }
}

deviceActivityLevel tanımları modlar arasında farklılık gösterir ve aşağıdaki değerlerden birine sahip olabilir:

Son cihaz etkinliği düzeyi Son bir saatteki standart istekler Son bir saatteki klasik istekler
LEVEL_1 (en düşük) Uygulama bu cihazda 10 veya daha az bütünlük jetonu istedi. Uygulama bu cihazda 5 veya daha az bütünlük jetonu istedi.
LEVEL_2 Uygulama bu cihazda 11 ile 25 arasında bütünlük jetonu istedi. Uygulama bu cihazda 6 ila 15 bütünlük jetonu istedi.
LEVEL_3 Uygulama bu cihazda 26 ile 50 arasında bütünlük jetonu istedi. Uygulama bu cihazda 16 ile 30 arasında bütünlük jetonu istedi.
LEVEL_4 (en yüksek) Uygulama bu cihazda 50'den fazla bütünlük jetonu istedi. Uygulama bu cihazda 30'dan fazla bütünlük jetonu istedi.
UNEVALUATED Son cihaz etkinliği değerlendirilmedi. Bunun nedeni aşağıdakilerden biri olabilir:
  • Cihaz yeterince güvenilir değildir.
  • Cihazda uygulamanızın Google Play tarafından tanınmayan bir sürümü yüklüdür.
  • Cihazdaki teknik sorunlar.

Hesap ayrıntıları alanı

accountDetails alanı, cihazda oturum açan kullanıcı hesabı için uygulamanın Google Play lisanslama durumunu temsil eden tek bir appLicensingVerdict değeri içerir. Kullanıcı hesabının uygulama için Play lisansı varsa uygulamayı indirmiş veya Google Play'den satın almış demektir.

accountDetails: {
  // This field can be LICENSED, UNLICENSED, or UNEVALUATED.
  appLicensingVerdict: "LICENSED"
}

appLicensingVerdict aşağıdaki değerlerden birine sahip olabilir:

LICENSED
Kullanıcının uygulamadan yararlanma hakkı var. Başka bir deyişle, kullanıcı, uygulamanızı Google Play'den yüklemiş veya satın almıştır.
UNLICENSED
Kullanıcının uygulamadan yararlanma hakkı yok. Bu durum, örneğin, kullanıcı uygulamanızı başka cihazdan yüklediğinde veya Google Play'den edinmediğinde meydana gelir. Bu sorunu düzeltmek için kullanıcılara GET_LICENSED iletişim kutusunu gösterebilirsiniz.
UNEVALUATED

Gerekli bir koşul karşılanmadığı için lisanslama ayrıntıları değerlendirilmemiştir.

Bu durum aşağıdakiler dahil olmak üzere çeşitli nedenlerden kaynaklanabilir:

  • Cihaz yeterince güvenilir değildir.
  • Cihazda uygulamanızın Google Play tarafından tanınmayan bir sürümü yüklüdür.
  • Kullanıcı Google Play'de oturum açmamıştır.

Kullanıcının uygulamanızla ilgili uygulamadan yararlanma hakkına sahip olup olmadığını kontrol etmek için appLicensingVerdict aşağıdaki kod snippet'inde gösterildiği gibi beklendiği gibi olduğunu doğrulayın:

Kotlin

val accountDetails = JSONObject(payload).getJSONObject("accountDetails")
val appLicensingVerdict = accountDetails.getString("appLicensingVerdict")

if (appLicensingVerdict == "LICENSED") {
    // Looks good!
}

Java

JSONObject accountDetails =
    new JSONObject(payload).getJSONObject("accountDetails");
String appLicensingVerdict = accountDetails.getString("appLicensingVerdict");

if (appLicensingVerdict.equals("LICENSED")) {
    // Looks good!
}

Ortam ayrıntıları alanı

Ortamla ilgili ek sinyalleri de etkinleştirebilirsiniz. Uygulamaya erişim riski; ekranı yakalamak, yer paylaşımlarını görüntülemek veya cihazı kontrol etmek için kullanılabilecek başka uygulamalar olup olmadığını uygulamanıza bildirir. Play Protect kararı, cihazda Google Play Protect'in etkinleştirilip etkinleştirilmediğini ve bilinen kötü amaçlı yazılım bulup bulmadığını bildirir.

Google Play Console'unuzda Uygulama Erişim Riski kararını veya Play Protect kararını etkinleştirdiyseniz API yanıtınızda environmentDetails alanı yer alır. environmentDetails alanı, appAccessRiskVerdict ve playProtectVerdict olmak üzere iki değer içerebilir.

Uygulamaya erişim riski kararı (beta)

Etkinleştirildikten sonra Play Integrity API yükündeki environmentDetails alanı, yeni uygulama erişim riski kararını içerir.

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
  environmentDetails: {
      appAccessRiskVerdict: {
          // This field contains one or more responses, for example the following.
          appsDetected: ["KNOWN_INSTALLED", "UNKNOWN_INSTALLED", "UNKNOWN_CAPTURING"]
      }
 }
}

Uygulamaya erişim riski değerlendirildiyse appAccessRiskVerdict, bir veya daha fazla yanıt içeren appsDetected alanını içerir. Bu yanıtlar, algılanan uygulamaların yükleme kaynağına bağlı olarak aşağıdaki iki gruptan birine girer:

  • Play veya sistem uygulamaları: Google Play tarafından yüklenen veya cihazın sistem bölümüne cihaz üreticisi tarafından önceden yüklenmiş olan uygulamalar (FLAG_SYSTEM ile tanımlanır). Bu tür uygulamaların yanıtlarının başında KNOWN_ bulunur.

  • Diğer uygulamalar: Google Play tarafından yüklenmemiş uygulamalar. Buna cihaz üreticisi tarafından sistem bölümüne önceden yüklenmiş uygulamalar dahil değildir. Bu tür uygulamaların yanıtlarının başında UNKNOWN_ bulunur.

Aşağıdaki yanıtlar döndürülebilir:

KNOWN_INSTALLED, UNKNOWN_INSTALLED
İlgili yükleme kaynağıyla eşleşen yüklü uygulamalar vardır.
KNOWN_CAPTURING, UNKNOWN_CAPTURING
Uygulamanız çalışırken ekranı görüntülemek için kullanılabilecek izinlere sahip, çalışan uygulamalar vardır. Google Play tarafından bilinen ve cihazda çalışan doğrulanmış erişilebilirlik hizmetleri buna dahil değildir.
KNOWN_CONTROLLING, UNKNOWN_CONTROLLING
Cihazı kontrol etmek ve uygulamanızdaki girişleri doğrudan kontrol etmek için kullanılabilen ve uygulamanızın girişlerini ve çıkışlarını yakalamak için kullanılabilen izinlere sahip uygulamalar bulunmaktadır. Google Play tarafından cihazda çalıştırıldığı bilinen doğrulanmış erişilebilirlik hizmetleri buna dahil değildir.
KNOWN_OVERLAYS, UNKNOWN_OVERLAYS
Uygulamanızda yer paylaşımlarını görüntülemek için kullanılabilecek izinlere sahip, çalışan uygulamalar var. Google Play tarafından bilinen ve cihazda çalışan doğrulanmış erişilebilirlik hizmetleri buna dahil değildir.
EMPTY (boş değer)

Gerekli bir şartın karşılanmaması durumunda uygulamaya erişim riski değerlendirilmez. Bu durumda appAccessRiskVerdict alanı boş olur. Bu durum, aşağıdakiler gibi çeşitli nedenlerle ortaya çıkabilir:

  • Cihaz yeterince güvenilir değildir.
  • Cihazın form faktörü telefon, tablet veya katlanabilir değil.
  • Cihazda, Android 6 (API düzeyi 23) veya sonraki bir sürüm yüklü olmamalıdır.
  • Cihazda uygulamanızın Google Play tarafından tanınmayan bir sürümü yüklüdür.
  • Cihazdaki Google Play Store sürümü eski.
  • Yalnızca oyunlar: Kullanıcı hesabının oyun için Play lisansı yoktur.

Uygulama erişim riski otomatik olarak, gelişmiş bir Google Play erişilebilirlik incelemesi (cihazdaki herhangi bir uygulama mağazası tarafından yüklenen) onaylanmış erişilebilirlik hizmetleri hariç tutulur. "Hariç tutuldu" durumu, cihazda çalışan doğrulanmış erişilebilirlik hizmetlerinin uygulama erişim riski kararında yakalama, kontrol etme veya yer paylaşımlı yanıt döndürmeyeceği anlamına gelir. Erişilebilirlik uygulamanıza yönelik gelişmiş bir Google Play erişilebilirlik incelemesi istemek için uygulamayı Google Play'de yayınlayın ve uygulamanızın manifest dosyasında isAccessibilityTool işaretinin "doğru" olarak ayarlandığından emin olun veya inceleme isteğinde bulunun.

Aşağıdaki tabloda bazı karar örnekleri ve bunların ne anlama geldiği verilmiştir (bu tabloda her olası sonuç listelenmez):

Örnek uygulama erişim riski kararı yanıtı Yorum
appsDetected:
["KNOWN_INSTALLED"]
Yalnızca Google Play tarafından tanınan veya cihaz üreticisi tarafından sistem bölümüne önceden yüklenmiş olan uygulamalar yüklüdür.
Çalışmakta olan ve yakalama, kontrol etme veya yerleştirme kararları ile sonuçlanabilecek uygulama yok.
appsDetected:
["KNOWN_INSTALLED",
"UNKNOWN_INSTALLED",
"UNKNOWN_CAPTURING"]
Google Play tarafından yüklenen veya cihaz üreticisi tarafından sistem bölümüne önceden yüklenmiş uygulamalar vardır.
Ekranı görüntülemek veya diğer giriş ve çıkışları yakalamak için kullanılabilecek, çalışan ve izinleri etkinleştirilmiş başka uygulamalar da vardır.
appsDetected:
["KNOWN_INSTALLED",
"KNOWN_CAPTURING",
"UNKNOWN_INSTALLED",
"UNKNOWN_CONTROLLING"]
Ekranı görüntülemek veya diğer giriş ve çıkışları yakalamak için kullanılabilecek izinlere sahip Play ya da çalışan sistem mevcut.
Cihazı kontrol etmek ve uygulamanıza yapılan girişleri doğrudan kontrol etmek için kullanılabilecek izinler etkinleştirilmiş, çalışan başka uygulamalar da vardır.
appAccessRiskVerdict: {} Gerekli bir koşul karşılanmadığı için uygulamaya erişim riski değerlendirilmemiştir. Örneğin, cihaz yeterince güvenilir değildir.

Risk düzeyinize bağlı olarak, hangi karar kombinasyonunun devam etmek için kabul edilebilir olduğuna ve hangi kararları almak istediğinize karar verebilirsiniz. Aşağıdaki kod snippet'inde, ekranı yakalayabilecek veya uygulamanızı kontrol edebilecek uygulama olmadığının doğrulanmasına dair bir örnek gösterilmektedir:

Kotlin

val environmentDetails =
    JSONObject(payload).getJSONObject("environmentDetails")
val appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict")

if (appAccessRiskVerdict.has("appsDetected")) {
    val appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}

Java

JSONObject environmentDetails =
    new JSONObject(payload).getJSONObject("environmentDetails");
JSONObject appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict");

if (appAccessRiskVerdict.has("appsDetected")) {
    String appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}

Play Protect kararı

Etkinleştirildiğinde Play Integrity API yükündeki environmentDetails alanı Play Protect kararını içerir:

environmentDetails: {
  playProtectVerdict: "NO_ISSUES"
}

playProtectVerdict aşağıdaki değerlerden birine sahip olabilir:

NO_ISSUES
Play Protect açıldı ve cihazda uygulama sorunu bulamadı.
NO_DATA
Play Protect açıldı ancak henüz tarama yapılmadı. Cihaz veya Play Store uygulaması kısa süre önce sıfırlanmış olabilir.
POSSIBLE_RISK
Play Protect kapalı.
MEDIUM_RISK
Play Protect açık ve cihazda zararlı olabilecek uygulamalar buldu.
HIGH_RISK
Play Protect açıldı ve cihazda yüklü tehlikeli uygulamalar buldu.
UNEVALUATED

Play Protect kararı değerlendirilmedi.

Bu durum aşağıdakiler dahil olmak üzere çeşitli nedenlerden kaynaklanabilir:

  • Cihaz yeterince güvenilir değildir.
  • Yalnızca oyunlar: Kullanıcı hesabının oyun için Play lisansı yoktur.

Play Protect kararını kullanma rehberi

Uygulamanızın arka uç sunucusu, risk toleransınıza bağlı olarak karara göre nasıl hareket edeceğine karar verebilir. Aşağıda bazı öneriler ve olası kullanıcı işlemleri verilmiştir:

NO_ISSUES
Play Protect açık olduğu için herhangi bir sorun bulmadığı için kullanıcının işlem yapmasına gerek yok.
POSSIBLE_RISK ve NO_DATA
Bu kararları alırken kullanıcıdan Play Protect'in açık olduğundan ve tarama gerçekleştirdiğinden emin olmasını isteyin. NO_DATA yalnızca nadir durumlarda görünmelidir.
MEDIUM_RISK ve HIGH_RISK
Risk toleransınıza bağlı olarak kullanıcıdan Play Protect'i başlatmasını ve Play Protect uyarılarıyla ilgili işlem yapmasını isteyebilirsiniz. Kullanıcı bu gereksinimleri karşılayamazsa sunucu işleminde onu engelleyebilirsiniz.