การตัดสินด้านความสมบูรณ์

หน้านี้อธิบายวิธีตีความและทำงานด้วยความสมบูรณ์ที่แสดงผลไว้ คำตัดสิน ไม่ว่าคุณจะส่งคำขอ API แบบมาตรฐานหรือคลาสสิก ความสมบูรณ์ ระบบจะส่งคำตัดสินในรูปแบบเดียวกันที่มีเนื้อหาคล้ายกัน ความสมบูรณ์ คำตัดสินสื่อสารข้อมูลเกี่ยวกับความถูกต้องของอุปกรณ์ แอป และ บัญชี เซิร์ฟเวอร์ของแอปสามารถใช้เพย์โหลดที่ได้ในการถอดรหัส เพื่อพิจารณาวิธีที่ดีที่สุดในการดำเนินการบางอย่าง หรือ ในแอปของคุณ

รูปแบบผลการตัดสินความสมบูรณ์ที่แสดงผล

เพย์โหลดจะเป็น JSON แบบข้อความธรรมดา และมีสัญญาณด้านความสมบูรณ์ควบคู่กัน ข้อมูลที่นักพัฒนาซอฟต์แวร์ให้ไว้

โครงสร้างเพย์โหลดทั่วไปมีดังนี้

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

ก่อนอื่นคุณต้องตรวจสอบว่าค่าในช่อง requestDetails ตรงกับค่าเหล่านั้น ของคำขอต้นฉบับก่อนตรวจสอบการตัดสินความสมบูรณ์แต่ละรายการ ดังต่อไปนี้ จะอธิบายแต่ละฟิลด์อย่างละเอียด

ช่องรายละเอียดคำขอ

ฟิลด์ requestDetails มีข้อมูลเกี่ยวกับคำขอ ได้แก่ ข้อมูลที่นักพัฒนาซอฟต์แวร์ให้ไว้ใน requestHash สำหรับคำขอมาตรฐานและ nonce สำหรับคำขอแบบคลาสสิก

สำหรับคำขอ API มาตรฐาน ให้ทำดังนี้

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

ค่าเหล่านี้ควรตรงกับค่าในคำขอเดิม ดังนั้น โปรดตรวจสอบ requestDetails ของเพย์โหลด JSON โดยตรวจสอบว่าส่วน requestPackageName และ requestHash ตรงกับสิ่งที่ส่งต้นฉบับ ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

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

สำหรับคำขอ API แบบคลาสสิก ให้ทำดังนี้

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

ค่าเหล่านี้ควรตรงกับค่าในคำขอเดิม ดังนั้น โปรดตรวจสอบ requestDetails ของเพย์โหลด JSON โดยตรวจสอบว่าส่วน requestPackageName และ nonce ตรงกับสิ่งที่ส่งในคำขอเดิมเป็น ที่แสดงในข้อมูลโค้ดต่อไปนี้

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

ช่องความสมบูรณ์ของแอปพลิเคชัน

ช่อง appIntegrity มีข้อมูลที่เกี่ยวข้องกับแพ็กเกจ

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 มีค่าต่อไปนี้ได้

PLAY_RECOGNIZED
แอปและใบรับรองตรงกับเวอร์ชันที่เผยแพร่โดย Google Play
UNRECOGNIZED_VERSION
ใบรับรองหรือชื่อแพ็กเกจไม่ตรงกับ Google เล่นแผ่นเสียง
UNEVALUATED
ระบบไม่ได้ประเมินความสมบูรณ์ของแอปพลิเคชัน ข้อกำหนดที่จำเป็น ขาดหายไป เช่น อุปกรณ์ไม่น่าเชื่อถือพอ

หากต้องการตรวจสอบว่าโทเค็นสร้างขึ้นโดยแอปที่คุณสร้างขึ้น โปรดยืนยัน ความสมบูรณ์ของแอปพลิเคชันเป็นไปตามที่คาดไว้ ดังที่แสดงในโค้ดต่อไปนี้ ตัวอย่าง:

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

คุณยังตรวจสอบชื่อแพ็กเกจแอป เวอร์ชันแอป และใบรับรองแอปได้ด้วย ด้วยตนเอง

ฟิลด์ความสมบูรณ์ของอุปกรณ์

ช่อง deviceIntegrity จะมีค่าได้เพียงค่าเดียว deviceRecognitionVerdict ที่มีป้ายกำกับอย่างน้อย 1 ป้ายระบุว่า สามารถบังคับใช้ความสมบูรณ์ของแอปได้ หากอุปกรณ์ไม่เป็นไปตามเกณฑ์ ป้ายกำกับ ช่อง deviceIntegrity ว่างเปล่า

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

โดยค่าเริ่มต้น deviceRecognitionVerdict สามารถมีสิ่งต่อไปนี้ได้

MEETS_DEVICE_INTEGRITY
แอปกำลังทำงานบนอุปกรณ์ที่ใช้ Android ที่มี บริการ Google Play อุปกรณ์ผ่านการตรวจสอบความสมบูรณ์ของระบบและเป็นไปตาม ข้อกำหนดด้านความเข้ากันได้กับ Android
ว่างเปล่า (ค่าว่าง)
แอปกำลังทำงานในอุปกรณ์ที่มีสัญญาณ การโจมตี (เช่น การฮุก API) หรือการบุกรุกระบบ (เช่น การรูท) หรือ แอปไม่ได้ทำงานบนอุปกรณ์จริง (เช่น โปรแกรมจำลองที่ ไม่ผ่านการตรวจสอบความสมบูรณ์ของ Google Play)

หากต้องการตรวจสอบว่าโทเค็นมาจากอุปกรณ์ที่เชื่อถือได้ โปรดยืนยัน deviceRecognitionVerdict เป็นไปตามที่คาดไว้ดังที่แสดงในโค้ดต่อไปนี้ ตัวอย่าง:

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

หากพบปัญหาเกี่ยวกับความสมบูรณ์ของอุปกรณ์ทดสอบการประชุม ตรวจสอบว่าได้ติดตั้ง ROM จากโรงงานแล้ว (เช่น โดยการรีเซ็ตอุปกรณ์) และ Bootloader ล็อกอยู่ นอกจากนี้ คุณยังสร้างการทดสอบ Play Integrity API ได้ด้วย ใน Play Console

ป้ายกำกับอุปกรณ์แบบมีเงื่อนไข

หากแอปมีการเผยแพร่ใน Google Play Games สำหรับ PC ระบบจะดำเนินการต่อไปนี้ deviceRecognitionVerdict จะมีป้ายกำกับต่อไปนี้ได้ด้วย:

MEETS_VIRTUAL_INTEGRITY
แอปกำลังทำงานบนโปรแกรมจำลองที่ขับเคลื่อนโดย Android บริการ Google Play โปรแกรมจำลองผ่านการตรวจสอบความสมบูรณ์ของระบบและเป็นไปตาม ข้อกำหนดหลักด้านความเข้ากันได้ของ Android

ข้อมูลอุปกรณ์ที่ไม่บังคับ

หากคุณเลือกรับข้อมูลเพิ่มเติม ป้ายกำกับในการตัดสินความสมบูรณ์ deviceRecognitionVerdict สามารถมีป้ายกำกับเพิ่มเติมต่อไปนี้ได้:

MEETS_BASIC_INTEGRITY
แอปกำลังทำงานบนอุปกรณ์ที่ผ่านการตรวจสอบขั้นพื้นฐาน การตรวจสอบความสมบูรณ์ของระบบ อุปกรณ์อาจไม่เป็นไปตามความเข้ากันได้ของ Android และอาจไม่ได้รับอนุมัติให้เรียกใช้บริการ Google Play สำหรับ ตัวอย่างเช่น อุปกรณ์อาจใช้ Android เวอร์ชันที่ไม่รู้จัก มี Bootloader ที่ปลดล็อกแล้ว หรืออาจไม่ได้รับการรับรองจาก ผู้ผลิต
MEETS_STRONG_INTEGRITY
แอปกำลังทำงานบนอุปกรณ์ที่ใช้ Android ที่มี บริการ Google Play และมีการรับประกันความสมบูรณ์ของระบบที่เข้มงวด เช่น หลักฐานยืนยันความสมบูรณ์ในการเปิดเครื่องที่ได้รับการสนับสนุนจากฮาร์ดแวร์ อุปกรณ์ผ่านระบบ การตรวจสอบความสมบูรณ์และเป็นไปตามข้อกําหนดความเข้ากันได้ของ Android

อุปกรณ์เครื่องเดียวจะแสดงป้ายกำกับอุปกรณ์หลายรายการในความสมบูรณ์ของอุปกรณ์ เพื่อดูว่าตรงกับเกณฑ์ของป้ายกำกับแต่ละรายการหรือไม่

กิจกรรมล่าสุดในอุปกรณ์

คุณยังเลือกใช้กิจกรรมล่าสุดในอุปกรณ์ได้ด้วย ซึ่งจะบอกวิธี แอปของคุณขอโทเค็นความสมบูรณ์ในอุปกรณ์หนึ่งๆ หลายครั้ง ในชั่วโมงที่แล้ว คุณสามารถใช้กิจกรรมล่าสุดในอุปกรณ์เพื่อปกป้องแอป อุปกรณ์ที่ไม่คาดคิดและไวต่อความรู้สึกซึ่งอาจบ่งบอกถึงการโจมตีที่กำลังดำเนินอยู่ คุณเลือกได้ว่าจะเชื่อถือระดับกิจกรรมล่าสุดแต่ละระดับในอุปกรณ์เท่าใดโดยอิงตาม บ่อยครั้งที่คุณคาดว่าแอปที่ติดตั้งในอุปกรณ์ทั่วไปจะส่งคำขอ โทเค็นความสมบูรณ์ในแต่ละชั่วโมง

หากคุณเลือกรับrecentDeviceActivityช่อง deviceIntegrity จะมี 2 ค่า ได้แก่

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

คำจำกัดความ deviceActivityLevel จะแตกต่างกันไปในแต่ละโหมดและอาจมี ค่าใดค่าหนึ่งต่อไปนี้

ระดับกิจกรรมล่าสุดในอุปกรณ์ คำขอโทเค็นความสมบูรณ์ของ API แบบมาตรฐานในอุปกรณ์นี้ ในช่วงชั่วโมงที่ผ่านมาต่อแอป คําขอโทเค็นความสมบูรณ์ของ API แบบคลาสสิกในอุปกรณ์นี้ ในช่วงชั่วโมงที่ผ่านมาต่อแอป
LEVEL_1 (ต่ำสุด) ไม่เกิน 10 5 หรือน้อยกว่า
LEVEL_2 ระหว่าง 11 ถึง 25 ระหว่าง 6 ถึง 10
LEVEL_3 ระหว่าง 26 ถึง 50 ระหว่าง 11 ถึง 15
LEVEL_4 (สูงสุด) มากกว่า 50 คน มากกว่า 15 คน
UNEVALUATED ระบบไม่ได้ประเมินกิจกรรมล่าสุดในอุปกรณ์ กรณีนี้อาจเกิดขึ้น เพราะ:
  • อุปกรณ์ไม่น่าเชื่อถือพอ
  • Google ไม่รู้จักเวอร์ชันของแอปที่ติดตั้งในอุปกรณ์ เล่น
  • ปัญหาทางเทคนิคในอุปกรณ์

ช่องรายละเอียดบัญชี

ฟิลด์ accountDetails มีค่าเดียวคือ appLicensingVerdict ซึ่ง แสดงสถานะการออกใบอนุญาต Google Play ของแอปสําหรับบัญชีผู้ใช้ที่ ลงชื่อเข้าใช้บนอุปกรณ์แล้ว หากบัญชีผู้ใช้มีใบอนุญาต Play สำหรับแอปนั้น แปลว่าผู้ใช้ดาวน์โหลด หรือซื้อ จาก Google Play

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

appLicensingVerdict อาจมีค่าใดค่าหนึ่งต่อไปนี้

LICENSED
ผู้ใช้มีสิทธิ์ในการใช้แอป กล่าวคือ ผู้ใช้ได้ติดตั้ง หรือซื้อแอปของคุณใน Google Play
UNLICENSED
ผู้ใช้ไม่มีสิทธิ์ในการใช้แอป กรณีนี้จะเกิดขึ้นเมื่อ เช่น ผู้ใช้โหลดแอปของคุณจากแหล่งที่ไม่รู้จักหรือไม่ได้ดาวน์โหลดแอปจาก Google Play คุณสามารถแสดงกล่องโต้ตอบ GET_LICENSED ต่อผู้ใช้เพื่อแก้ไขปัญหานี้
UNEVALUATED

ไม่มีการประเมินรายละเอียดการอนุญาตให้ใช้สิทธิเนื่องจากมี ไม่เป็นไปตามข้อกำหนด

ปัญหานี้อาจเกิดขึ้นได้จากหลายสาเหตุ เช่น

  • อุปกรณ์ไม่น่าเชื่อถือพอ
  • Google ไม่รู้จักเวอร์ชันของแอปที่ติดตั้งในอุปกรณ์ เล่น
  • ผู้ใช้ไม่ได้ลงชื่อเข้าใช้ Google Play

หากต้องการตรวจสอบว่าผู้ใช้มีสิทธิ์ใช้แอปสำหรับแอปของคุณไหม ให้ตรวจสอบว่า appLicensingVerdict เป็นไปตามที่คาดไว้ ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

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

ช่องรายละเอียดสภาพแวดล้อม

คุณสามารถเลือกรับสัญญาณเพิ่มเติมเกี่ยวกับสภาพแวดล้อมได้ด้วย การเข้าถึงแอป จะบอกแอปของคุณหากมีแอปอื่นๆ ทำงานอยู่ที่อาจใช้เพื่อ จับภาพหน้าจอ แสดงการวางซ้อน หรือควบคุมอุปกรณ์ Play Protect ผลการตรวจสอบจะบอกคุณว่าได้เปิดใช้ Google Play Protect ในอุปกรณ์แล้วหรือไม่และ พบมัลแวร์ที่รู้จัก

หากคุณเลือกใช้คำตัดสินความเสี่ยงในการเข้าถึงแอปหรือผลการตัดสิน Play Protect ใน Google Play Console การตอบกลับจาก API จะรวม environmentDetails ฟิลด์ environmentDetails สามารถมีได้ 2 รายการ ค่า appAccessRiskVerdict และ playProtectVerdict

คำตัดสินความเสี่ยงในการเข้าถึงแอป (เบต้า)

เมื่อเปิดใช้แล้ว ช่อง environmentDetails ใน Play Integrity API เพย์โหลดจะมี คำตัดสินความเสี่ยงในการเข้าถึงแอปใหม่

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

หากมีการประเมินความเสี่ยงในการเข้าถึงแอปแล้ว appAccessRiskVerdict จะมีช่องนี้ appsDetected ที่มีการตอบกลับอย่างน้อย 1 รายการ คำตอบเหล่านี้จัดอยู่ใน 2 กลุ่มต่อไปนี้โดยขึ้นอยู่กับแหล่งที่มาของการติดตั้งของแอปที่ตรวจพบ

  • แอป Play หรือแอประบบ: แอปที่ติดตั้งโดย Google Play หรือโหลดไว้ล่วงหน้า โดยผู้ผลิตอุปกรณ์ในพาร์ติชันระบบของอุปกรณ์ (ระบุด้วย FLAG_SYSTEM) การตอบสนองสำหรับแอปดังกล่าวจะมี KNOWN_ นำหน้า

  • แอปอื่นๆ: แอปที่ Google Play ไม่ได้ติดตั้ง ซึ่งไม่รวม แอปที่โหลดไว้ล่วงหน้าในพาร์ติชันระบบโดยผู้ผลิตอุปกรณ์ การตอบกลับ สำหรับแอปดังกล่าวจะมี UNKNOWN_ นำหน้า

การตอบกลับที่ส่งคืนได้มีดังนี้

KNOWN_INSTALLED, UNKNOWN_INSTALLED
มีแอปที่ติดตั้งซึ่งตรงกับแหล่งที่มาของการติดตั้งที่เกี่ยวข้อง
KNOWN_CAPTURING, UNKNOWN_CAPTURING
มีแอปที่ทำงานอยู่ซึ่งเปิดใช้สิทธิ์ ซึ่งอาจใช้เพื่อ ดูหน้าจอขณะที่แอปทำงานอยู่ ยกเว้นรายการที่ยืนยันแล้ว บริการช่วยเหลือพิเศษที่ Google Play รู้จักซึ่งทำงานอยู่ในอุปกรณ์
KNOWN_CONTROLLING, UNKNOWN_CONTROLLING
มีแอปที่ทำงานอยู่ซึ่งเปิดใช้สิทธิ์ ซึ่งอาจใช้เพื่อ ควบคุมอุปกรณ์และควบคุมอินพุต ไปยังแอปของคุณได้โดยตรง และอาจ ซึ่งใช้เพื่อบันทึกอินพุตและเอาต์พุตของแอป ยกเว้นรายการที่ยืนยันแล้ว บริการช่วยเหลือพิเศษที่ Google Play รู้จักซึ่งทำงานอยู่ในอุปกรณ์
KNOWN_OVERLAYS, UNKNOWN_OVERLAYS
มีแอปที่ทำงานอยู่ซึ่งเปิดใช้สิทธิ์ ซึ่งอาจใช้เพื่อ แสดงการวางซ้อนบนแอปของคุณ ยกเว้นการช่วยเหลือพิเศษที่ยืนยันแล้ว บริการที่ Google Play ทราบว่าทำงานบนอุปกรณ์นั้น
EMPTY (ค่าว่าง)

ระบบไม่ได้ประเมินความเสี่ยงในการเข้าถึงแอปหากไม่มีการปฏิบัติตามข้อกำหนดที่จำเป็น ใน ในกรณีนี้ ช่อง appAccessRiskVerdict ว่างเปล่า กรณีนี้อาจเกิดขึ้นกับ เนื่องจากสาเหตุหลายประการดังนี้

  • อุปกรณ์ไม่น่าเชื่อถือพอ
  • รูปแบบของอุปกรณ์ไม่ใช่โทรศัพท์ แท็บเล็ต หรืออุปกรณ์แบบพับได้
  • อุปกรณ์ไม่ได้ใช้ Android 6 (API ระดับ 23) ขึ้นไป
  • Google Play ไม่รู้จักเวอร์ชันของแอปที่ติดตั้งในอุปกรณ์
  • Google Play Store ในอุปกรณ์เป็นเวอร์ชันเก่า
  • เกมเท่านั้น: บัญชีผู้ใช้ไม่มีใบอนุญาต Play สำหรับเกม

ความเสี่ยงในการเข้าถึงแอปจะยกเว้นบริการการช่วยเหลือพิเศษที่ยืนยันแล้วโดยอัตโนมัติ ซึ่ง ได้ผ่านการตรวจสอบการช่วยเหลือพิเศษที่มีประสิทธิภาพมากขึ้นของ Google Play (ซึ่งติดตั้งโดย App Store ใดก็ได้ในอุปกรณ์) "ยกเว้น" หมายความว่าการเข้าถึง ที่ได้รับการยืนยัน บริการที่ทำงานอยู่ในอุปกรณ์จะไม่ส่งกลับการจับภาพ การควบคุม หรือ การตอบสนองการวางซ้อนในผลการตัดสินความเสี่ยงในการเข้าถึงแอป หากต้องการขอรับบริการขั้นสูงสำหรับ เปิดรีวิวการช่วยเหลือพิเศษสำหรับแอปการช่วยเหลือพิเศษ และเผยแพร่ใน Google เล่นเพื่อตรวจสอบว่าแอปได้ตั้งค่า Flag isAccessibilityTool เป็น "จริง" ไฟล์ Manifest ของแอป หรือขอรับการตรวจสอบ

ตารางต่อไปนี้แสดงตัวอย่างการตัดสินและความหมายของการตัดสิน (นี่คือ ตารางไม่ได้แสดงรายการผลลัพธ์ที่เป็นไปได้ทั้งหมด):

ตัวอย่างการตอบกลับผลการตัดสินความเสี่ยงในการเข้าถึงแอป การตีความ
appsDetected:
["KNOWN_INSTALLED"]
มีเพียงแอปที่ติดตั้งซึ่ง Google Play รู้จักหรือโหลดไว้ล่วงหน้าในพาร์ติชันระบบโดยผู้ผลิตอุปกรณ์
ไม่มีแอปที่ทำงานอยู่ที่จะทำให้เกิดผลการจับภาพ การควบคุม หรือการวางซ้อน
appsDetected:
["KNOWN_INSTALLED",
"UNKNOWN_INSTALLED",
"UNKNOWN_CAPTURING"]
มีแอปที่ติดตั้งโดย Google Play หรือผู้ผลิตอุปกรณ์โหลดไว้ล่วงหน้าในพาร์ติชันระบบ
มีแอปอื่นๆ ที่ทำงานอยู่และมีการเปิดใช้สิทธิ์ซึ่งสามารถใช้เพื่อดูหน้าจอหรือจับภาพอินพุตและเอาต์พุตอื่นๆ
appsDetected:
["KNOWN_INSTALLED",
"KNOWN_CAPTURING",
"UNKNOWN_INSTALLED",
"UNKNOWN_CONTROLLING"]
มี Play หรือระบบที่กำลังทำงานซึ่งเปิดใช้สิทธิ์ต่างๆ เพื่อใช้ดูหน้าจอหรือจับภาพอินพุตและเอาต์พุตอื่นๆ ได้
นอกจากนี้ ยังมีแอปอื่นๆ ที่ใช้งานอยู่ซึ่งเปิดใช้สิทธิ์เพื่อควบคุมอุปกรณ์และควบคุมอินพุตที่ป้อนลงในแอปได้โดยตรง
appAccessRiskVerdict: {} ไม่ได้ประเมินความเสี่ยงในการเข้าถึงแอปเนื่องจากไม่เป็นไปตามข้อกำหนดที่จำเป็น เช่น อุปกรณ์ไม่น่าเชื่อถือพอ

คุณตัดสินใจได้ว่าจะผสมผสานคำตัดสินใด ทั้งนี้ขึ้นอยู่กับระดับความเสี่ยงของคุณ ยอมรับให้ดำเนินการต่อ และคำตัดสินที่คุณต้องการดำเนินการตาม ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างของการยืนยันว่าไม่มี แอปที่ทำงานอยู่ที่สามารถจับภาพหน้าจอหรือควบคุมแอปของคุณ

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!
    }
}
แก้ไขผลการตัดสินความเสี่ยงในการเข้าถึงแอป

คุณสามารถตัดสินใจได้ว่าจะตัดสินความเสี่ยงในการเข้าถึงแอปแบบใด ทั้งนี้ขึ้นอยู่กับระดับความเสี่ยงของคุณ ต้องการดำเนินการก่อนที่จะให้ผู้ใช้ดำเนินการตามคำขอหรือดำเนินการจนเสร็จสมบูรณ์ มีข้อความแจ้งของ Google Play ที่ไม่บังคับให้คุณแสดงแก่ผู้ใช้หลังจาก ตรวจสอบผลการตัดสินความเสี่ยงในการเข้าถึงแอป คุณสามารถแสดง CLOSE_UNKNOWN_ACCESS_RISK เพื่อขอให้ผู้ใช้ปิดแอปที่ไม่รู้จักซึ่งทำให้เกิด คำตัดสินความเสี่ยงในการเข้าถึงแอปหรือคุณสามารถแสดง CLOSE_ALL_ACCESS_RISK เพื่อขอ ผู้ใช้ปิดแอปทั้งหมด (รู้จักและไม่รู้จัก) ซึ่งส่งผลให้คำตัดสินความเสี่ยงในการเข้าถึงแอป

การตัดสินของ Play Protect

เมื่อเปิดใช้แล้ว ช่อง environmentDetails ใน Play Integrity API เพย์โหลดจะมี คำตัดสินของ Play Protect มีดังนี้

environmentDetails: {
  playProtectVerdict: "NO_ISSUES"
}

playProtectVerdict อาจมีค่าใดค่าหนึ่งต่อไปนี้

NO_ISSUES
Play Protect เปิดอยู่และไม่พบปัญหาเกี่ยวกับแอปในอุปกรณ์
NO_DATA
Play Protect เปิดอยู่แต่ยังไม่ได้สแกน อุปกรณ์หรือ อาจมีการรีเซ็ตแอป Play Store เมื่อเร็วๆ นี้
POSSIBLE_RISK
Play Protect ปิดอยู่
MEDIUM_RISK
Play Protect เปิดอยู่และพบแอปที่อาจเป็นอันตรายติดตั้งอยู่ ในอุปกรณ์
HIGH_RISK
Play Protect เปิดอยู่และพบแอปอันตรายติดตั้งใน อุปกรณ์
UNEVALUATED

ยังไม่มีการประเมินคำตัดสิน Play Protect

ปัญหานี้อาจเกิดขึ้นได้จากหลายสาเหตุ เช่น

  • อุปกรณ์ไม่น่าเชื่อถือพอ
  • เกมเท่านั้น: บัญชีผู้ใช้ไม่มีใบอนุญาต Play สำหรับเกม

คำแนะนำในการใช้คำตัดสินของ Play Protect

เซิร์ฟเวอร์แบ็กเอนด์ของแอปสามารถเลือกการดําเนินการได้โดยอิงตามคำตัดสิน การยอมรับความเสี่ยงของคุณ คำแนะนำและการดำเนินการที่ผู้ใช้อาจทำได้มีดังนี้

NO_ISSUES
Play Protect เปิดอยู่และไม่พบปัญหาใดๆ ผู้ใช้จึงไม่ต้องดำเนินการใดๆ
POSSIBLE_RISK และ NO_DATA
เมื่อได้รับผลการตัดสินเหล่านี้แล้ว โปรดขอให้ผู้ใช้ตรวจสอบว่า Play Protect เปิดอยู่หรือไม่ และได้ทำการสแกน NO_DATA ควรปรากฏในบางกรณีเท่านั้น
MEDIUM_RISK และ HIGH_RISK
คุณขอให้ผู้ใช้เปิด Play ได้โดยขึ้นอยู่กับการยอมรับความเสี่ยงของคุณ ปกป้องและดำเนินการกับคำเตือนของ Play Protect หากผู้ใช้ไม่สามารถกรอกข้อมูลได้ ข้อกำหนดเหล่านี้สามารถบล็อก จากการทำงานของเซิร์ฟเวอร์ได้