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. Standart veya klasik API isteği göndermiş olmanıza bakılmaksızın entegrasyon 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 sunar. Uygulamanızın sunucusu, şifresi çözülmüş ve doğrulanmış bir karardaki yükü kullanarak uygulamanızda belirli bir işlem veya istekle ilgili izlenecek en iyi yolu belirleyebilir.

Döndürülen entegrasyon kararı biçimi

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

Genel yükü yapısı aşağıdaki gibidir:

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

Her entegrasyon kararını kontrol etmeden önce requestDetails alanındaki değerlerin orijinal istekteki değerlerle eşleştiğinden emin olmanız gerekir. Aşağıdaki bölümlerde her alan ayrıntılı olarak açıklanmıştır.

İstek ayrıntıları alanı

requestDetails alanında istekle ilgili bilgiler yer alır. Standart istekler için requestHash alanında, klasik istekler için de nonce alanında geliştirici tarafından sağlanan bilgiler buna dahildir.

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 requested.
  timestampMillis: "1675655009345"
}

Bu değerler, orijinal istekteki değerlerle eşleşmelidir. Bu nedenle, JSON yükünün requestDetails bölümünü doğrulamak için requestPackageName ve requestHash değerlerinin aşağıdaki kod snippet'inde gösterildiği gibi orijinal istekte gönderilenlerle eşleştiğinden emin olun:

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 istekteki değerlerle eşleşmelidir. Bu nedenle, JSON yükünün requestDetails bölümünü doğrulamak için requestPackageName ve nonce değerlerinin aşağıdaki kod snippet'inde gösterildiği gibi orijinal istekte gönderilenlerle eşleştiğinden emin olun:

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ğerleri alabilir:

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ğerlendirilmemiştir. Koşullardan biri karşılanmamıştır (örneğin, cihaz yeterince güvenilir olmayabilir).

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 paket adını, uygulama sürümünü ve uygulama sertifikalarını manuel olarak da kontrol edebilirsiniz.

Cihaz bütünlüğü alanı

deviceIntegrity alanında, bir cihazın uygulama bütünlüğünü ne kadar iyi uygulayabildiğini gösteren bir veya daha fazla etiket içeren tek bir değer ("deviceRecognitionVerdict") bulunabilir. Cihaz hiçbir etiketin ölçütlerini karşılamıyorsa deviceIntegrity alanı boş bırakılır.

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 kullanıldığı Android destekli bir cihazda çalışmaktadır. Cihaz, sistem bütünlüğü kontrollerini geçer ve Android uyumluluk koşullarını karşılar.
Boş (boş değer)
Uygulamanın çalıştığı cihazda saldırı (API kancalama gibi) veya sistem bozulması (rootlanma gibi) belirtileri var ya da uygulama fiziksel bir cihazda çalışmıyor (örneğin, Google Play bütünlük kontrollerini geçmeyen bir emülatörde çalışıyor).

Jetonun güvenilir bir cihazdan geldiğinden emin olmak için aşağıdaki kod snippet'inde gösterildiği gibi deviceRecognitionVerdict değerinin 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 sorun yaşıyorsanız fabrika ROM'unun yüklü olduğundan (ör. cihazı sıfırlayarak) ve önyükleyicinin kilitli olduğundan emin olun. Ayrıca Play Console'da Play Integrity API testleri oluşturabilirsiniz.

Koşullu cihaz etiketleri

Uygulamanız PC Üzerinde Google Play Games'de yayınlanıyorsa deviceRecognitionVerdict aşağıdaki etiketi de içerebilir:

MEETS_VIRTUAL_INTEGRITY
Uygulama, Google Play Hizmetleri'nin kullanıldığı Android destekli bir cihazda çalışıyor. Emülatör, sistem bütünlüğü kontrollerini geçer ve temel Android uyumluluk şartlarını karşılar.

İsteğe bağlı cihaz bilgileri

Bütünlük kararında ek etiketler almayı etkinleştirirseniz deviceRecognitionVerdict aşağıdaki ek etiketleri içerebilir:

MEETS_BASIC_INTEGRITY
Uygulama, temel sistem bütünlük kontrollerini geçen bir cihazda çalışıyor ve Android 13 veya sonraki sürüm cihazlarda Android Platform Anahtar Onayı'nı gerektiriyor. Cihaz, Android uyumluluk koşullarını karşılamayabilir ve Google Play Hizmetleri'ni çalıştırmak üzere onaylanmamış olabilir. Örneğin, cihaz Android'in tanınmayan bir sürümü çalıştırıyor, kilidi açılmış bir bootloader içeriyor, doğrulanmamış bir önyükleme yapıyor veya üretici tarafından sertifikalandırılmamış olabilir.
MEETS_STRONG_INTEGRITY
Uygulama, Google Play Hizmetleri'nin yüklü olduğu Android destekli bir cihazda çalışmaktadır ve sistem bütünlüğü, donanım destekli bir önyükleme bütünlüğü kanıtı gibi güçlü bir araçla garanti altına alınmıştır. Ayrıca Android 13 veya sonraki sürümlerin yüklü olduğu cihazlarda son bir yıl içinde bir güvenlik güncellemesi yapılmış olmalıdır. Cihaz, sistem bütünlüğü kontrollerini geçer ve Android uyumluluk koşullarını karşılar.

Bir cihaz, etiketin ölçütlerinin her biri karşılandığı takdirde cihaz bütünlüğü kararında birden çok cihaz etiketi döndürür.

Son cihaz etkinliği

Ayrıca, uygulamanızın son bir saat içinde belirli bir cihazda kaç kez bütünlük jetonu istediğini belirten son cihaz etkinliği özelliğini de etkinleştirebilirsiniz. Uygulamanızı, etkin bir saldırının göstergesi olabilecek beklenmedik, hiperaktif cihazlara karşı korumak için son cihaz etkinliğini kullanabilirsiniz. Her bir son cihaz etkinliği seviyesine ne kadar güveneceğinize, tipik bir cihaza yüklenen uygulamanızın her saatte kaç kez bütünlük jetonu isteyeceğini tahmin ederek karar verebilirsiniz.

recentDeviceActivity'ü almayı etkinleştirirseniz deviceIntegrity alanının iki değeri olur:

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 seviyesi Bu cihazda son bir saat içinde uygulama başına standart API bütünlük jetonu istekleri Son bir saat içinde bu cihazda uygulama başına klasik API bütünlük jetonu istekleri
LEVEL_1 (en düşük) 10 veya daha az 5 veya daha az
LEVEL_2 11 ile 25 arasında 6 ile 10 arasında
LEVEL_3 26 ile 50 arasında 11 ila 15
LEVEL_4 (en yüksek) 50'den fazla 15'ten fazla
UNEVALUATED Son cihaz etkinliği değerlendirilmemiştir. Bunun nedeni şunlar 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.

Cihaz özellikleri

Cihaz özelliklerini de etkinleştirebilirsiniz. Bu özellik, cihazda çalışan Android OS'in Android SDK sürümünü belirtir. Bu özellik gelecekte diğer cihaz özellikleriyle genişletilebilir.

SDK sürümü değeri, Build.VERSION_CODES içinde tanımlanan Android SDK sürüm numarasıdır. Gerekli koşullardan biri karşılanmadıysa SDK sürümü değerlendirilmez. Bu durumda sdkVersion alanının değeri belirlenmemiştir. Bu nedenle deviceAttributes alanı boştur. 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.
  • Cihazda teknik sorunlar vardı.

deviceAttributes almayı etkinleştirirseniz deviceIntegrity alanında aşağıdaki ek alan bulunur:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  deviceAttributes: {
    // 33 is one possible value, which represents Android 13 (Tiramisu).
    sdkVersion: 33
  }
}

SDK sürümü değerlendirilmezse deviceAttributes alanı aşağıdaki gibi ayarlanır:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  deviceAttributes: {}  // sdkVersion field is not set.
}

Hesap ayrıntıları alanı

accountDetails alanında, cihazda oturum açmış kullanıcı hesabı için uygulamanın Google Play lisanslama durumunu gösteren tek bir değer (appLicensingVerdict) bulunur. Kullanıcı hesabında uygulamanın Play lisansı varsa kullanıcı uygulamayı Google Play'den indirmiş veya satın almış demektir.

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

appLicensingVerdict aşağıdaki değerlerden biri olabilir:

LICENSED
Kullanıcının uygulamadan yararlanma hakkı bulunmaktadır. Yani kullanıcı, uygulamanızı cihazında Google Play'den yüklemiş veya güncellemiştir.
UNLICENSED
Kullanıcının uygulamadan yararlanma hakkı yoktur. Kullanıcının uygulamanızı başka cihazdan yüklediği veya Google Play dışında bir kanaldan edindiği durumlarda bu etiket görülür. Bu sorunu düzeltmek için kullanıcılara GET_LICENSED iletişimini gösterebilirsiniz.
UNEVALUATED

Koşullardan biri 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ız için uygulama hakkına sahip olup olmadığını kontrol etmek amacıyla, aşağıdaki kod snippet'inde gösterildiği gibi appLicensingVerdict değerinin 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. Uygulama erişim riski, uygulamanıza ekranı kaydetmek, yer paylaşımları görüntülemek veya cihazı kontrol etmek için kullanılabilecek başka uygulamaların çalışıp çalışmadığını bildirir. Play Protect kararı, Google Play Protect'in cihazda etkin olup olmadığını ve bilinen kötü amaçlı yazılım bulup bulmadığını belirtir.

Google Play Console'da uygulama erişim riski kararını veya Play Protect kararını etkinleştirdiyseniz API yanıtınızda environmentDetails alanı bulunur. environmentDetails alanı appAccessRiskVerdict ve playProtectVerdict olmak üzere iki değer içerebilir.

Uygulamaya erişim riski kararı

Bu özellik 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"]
      }
 }
}

Uygulama erişim riski değerlendirildiyse appAccessRiskVerdict, bir veya daha fazla yanıt içeren appsDetected alanını içerir. Bu yanıtlar, tespit edilen 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 üreticisi tarafından cihazın sistem bölümüne önceden yüklenen uygulamalar (FLAG_SYSTEM ile tanımlanır). Bu tür uygulamalara verilen yanıtların önüne KNOWN_ ön eki eklenir.

  • Diğer uygulamalar: Google Play tarafından yüklenmeyen uygulamalar. Cihaz üreticisi tarafından sistem bölümüne önceden yüklenmiş uygulamalar bu kapsamda değildir. Bu tür uygulamalara verilen yanıtların önüne UNKNOWN_ ön eki eklenir.

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

KNOWN_INSTALLED, UNKNOWN_INSTALLED
İlgili yükleme kaynağıyla eşleşen uygulamalar yüklü.
KNOWN_CAPTURING, UNKNOWN_CAPTURING
Uygulamanız çalışırken ekranı görüntülemek için kullanılabilecek izinleri etkinleştirilmiş çalışan uygulamalar var. Google Play'in cihazda çalıştığı bilinen doğrulanmış erişilebilirlik hizmetleri bu kapsamda değildir.
KNOWN_CONTROLLING, UNKNOWN_CONTROLLING
Cihazınızı kontrol etmek ve uygulamanıza gelen girişleri doğrudan kontrol etmek için kullanılabilecek izinlerin etkin olduğu çalışan uygulamalar var. Bu uygulamalar, uygulamanızın giriş ve çıkışlarını yakalamak için de kullanılabilir. Google Play'in cihazda çalıştığını bildiği doğrulanmış erişilebilirlik hizmetleri bu kapsamda değildir.
KNOWN_OVERLAYS, UNKNOWN_OVERLAYS
Uygulamanızda yer paylaşımları görüntülemek için kullanılabilecek izinlerin etkin olduğu çalışan uygulamalar var. Bu, cihazda Google Play tarafından bilinen doğrulanmış erişilebilirlik hizmetlerini kapsamaz.
Boş (boş değer)

Koşullardan biri karşılanmadığı için uygulama erişim riski değerlendirilmez. Bu durumda appAccessRiskVerdict alanı boştur. Bu durum aşağıdakiler dahil olmak üzere çeşitli nedenlerden kaynaklanabilir:

  • Cihaz yeterince güvenilir değildir.
  • Cihaz form faktörü telefon, tablet veya katlanabilir değil.
  • Cihazınızda Android 6 (API düzeyi 23) veya sonraki sürümler yüklü değil.
  • 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ü güncel değildir.
  • Yalnızca oyunlar: Kullanıcı hesabında oyun için Play lisansı yoktur.
  • verdictOptOut parametresi ile standart bir istek kullanıldı.
  • Standart istek için henüz uygulama erişim riskini desteklemeyen bir Play Integrity API kitaplığı sürümü ile standart istek kullanıldı.

Uygulama erişim riski, gelişmiş Google Play erişilebilirlik incelemesinden geçmiş doğrulanmış erişilebilirlik hizmetlerini (cihazdaki herhangi bir uygulama mağazası tarafından yüklenir) otomatik olarak hariç tutar. "Hariç tutuldu", cihazda çalışan doğrulanmış erişilebilirlik hizmetlerinin, uygulama erişimi riski kararında yakalama, kontrol etme veya yer paylaşımı yanıtı döndürmeyeceği anlamına gelir. Erişilebilirlik uygulamanız için gelişmiş Google Play erişilebilirlik incelemesi isteğinde bulunmak istiyorsanız uygulamanızı Google Play'de yayınlayın ve uygulamanızın manifest dosyasında isAccessibilityTool işaretinin true olarak ayarlandığından emin olun veya inceleme isteğinde bulunun.

Aşağıdaki tabloda, karar örnekleri ve bunların ne anlama geldiği verilmiştir (bu tabloda olası tüm sonuçlar listelenmez):

Uygulamaya erişim riski kararı örneği Yorumlama
appsDetected:
["KNOWN_INSTALLED"]
Yalnızca Google Play tarafından tanınan veya cihaz üreticisi tarafından sistem bölümüne önceden yüklenen uygulamalar yüklüdür.
Kayıt, kontrol veya yer paylaşımı kararlarıyla sonuçlanacak şekilde çalışan hiçbir uygulama yoktur.
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üklenen uygulamalar vardır.
Ekranı görüntülemek veya diğer giriş ve çıkışları yakalamak için kullanılabilecek izinleri etkinleştirilmiş ve çalışan başka uygulamalar 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 izinlerin etkin olduğu Play veya sistem çalışıyor.
Ayrıca, cihazı kontrol etmek ve uygulamanıza yapılan girişleri doğrudan kontrol etmek için kullanılabilecek izinleri etkinleştirilmiş başka uygulamalar da çalışır.
appAccessRiskVerdict: {} Koşullardan biri karşılanmadığı için uygulama erişimi riski değerlendirilmemiştir. Örneğin, cihaz yeterince güvenilir olmayabilir.

Risk düzeyinize bağlı olarak, devam etmek için hangi karar kombinasyonlarının kabul edilebilir olduğuna ve hangi kararlar için işlem yapmak istediğinize karar verebilirsiniz. Aşağıdaki kod snippet'inde, ekranı kaydedebilecek veya uygulamanızı kontrol edebilecek uygulamaların çalışıp çalışmadığını doğrulama örneği 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!
    }
}
Uygulamaya erişim riski kararlarını düzeltme

Risk düzeyinize bağlı olarak, kullanıcının bir isteği veya işlemi tamamlamasına izin vermeden önce hangi uygulama erişim riski kararları için işlem yapmak istediğinize karar verebilirsiniz. Uygulama erişim riski sonucunu kontrol ettikten sonra kullanıcıya gösterebileceğiniz isteğe bağlı Google Play istemleri vardır. Kullanıcıdan uygulama erişim riski kararına neden olan bilinmeyen uygulamaları kapatmasını istemek için CLOSE_UNKNOWN_ACCESS_RISK'i veya kullanıcıdan uygulama erişim riski kararına neden olan tüm uygulamaları (bilinen ve bilinmeyen) kapatmasını istemek için CLOSE_ALL_ACCESS_RISK'i gösterebilirsiniz.

Play Protect kararı

Etkinleştirildikten sonra Play Integrity API yükündeki environmentDetails alanı Play Protect kararını içerir:

environmentDetails: {
  playProtectVerdict: "NO_ISSUES"
}

playProtectVerdict aşağıdaki değerlerden biri olabilir:

NO_ISSUES
Play Protect etkindir ve cihazda uygulama ile ilgili herhangi bir sorun tespit edilmemiştir.
NO_DATA
Play Protect etkindir ancak henüz tarama yapılmamıştır. Cihaz ya da Play Store uygulaması kısa süre önce sıfırlanmış olabilir.
POSSIBLE_RISK
Play Protect kapalı.
MEDIUM_RISK
Play Protect etkindir ve cihazda potansiyel olarak zararlı uygulamaların yüklü olduğunu tespit etmiştir.
HIGH_RISK
Play Protect etkindir ve cihazda tehlikeli uygulamaların yüklü olduğunu tespit etmiştir.
UNEVALUATED

Play Protect kararı değerlendirilmemiştir.

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

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

Play Protect kararının kullanımıyla ilgili kılavuz

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

NO_ISSUES
Play Protect açıktır ve herhangi bir sorun tespit etmediğinden kullanıcının herhangi bir işlem yapmasına gerek yoktur.
POSSIBLE_RISK ve NO_DATA
Bu sonuçlar alındığında kullanıcıdan Play Protect'in açık olup olmadığını ve tarama yapıp yapmadığını kontrol etmesini isteyin. NO_DATA yalnızca nadir durumlarda gösterilir.
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ı hakkında işlem yapmasını isteyebilirsiniz. Kullanıcı bu koşulları karşılayamıyorsa sunucu işlemini engelleyebilirsiniz.