このページでは、返された完全性判定の結果の解釈とその対応について説明します。標準 API リクエストとクラシック 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 requested. timestampMillis: "1675655009345" }
これらの値は、元のリクエストの値と一致する必要があります。したがって、次のコード スニペットに示すように、requestPackageName
と requestHash
が元のリクエストで送信されたものと一致することを確認して、JSON ペイロードの requestDetails
の部分を検証します。
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" }
これらの値は、元のリクエストの値と一致する必要があります。したがって、次のコード スニペットに示すように、requestPackageName
と nonce
が元のリクエストで送信されたものと一致することを確認して、JSON ペイロードの requestDetails
の部分を検証します。
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 Play の記録と一致しません。
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
- アプリは Google Play 開発者サービスを備えた Android デバイスで実行されています。このデバイスはシステム完全性チェックに合格し、Android の互換性要件を満たしています。
- 空(空の値)
- アプリは、API フックなどの攻撃や root 権限取得などのシステム侵害の兆候があるデバイス、または 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 がインストールされていることと、ブートローダーがロックされていることを確認してください(前者はデバイスをリセットするなどの方法で確認できます)。また、Google Play Console で Play Integrity API テストを作成することもできます。
条件付きのデバイスラベル
アプリを PC 版 Google Play Games にリリースする場合は、deviceRecognitionVerdict
に次のラベルを付けることもできます。
MEETS_VIRTUAL_INTEGRITY
- アプリは Google Play 開発者サービスを備えた Android エミュレータで実行されています。このエミュレータはシステム完全性チェックに合格し、Android の互換性に関する主要な要件を満たしています。
オプションのデバイス情報
完全性判定の結果で追加ラベルを受け取ることをオプトインすると、deviceRecognitionVerdict
に以下のラベルを追加できます。
MEETS_BASIC_INTEGRITY
- アプリは、基本的なシステム完全性チェックに合格したデバイスで動作しています。このデバイスは Android の互換性要件を満たしておらず、Google Play 開発者サービスの実行を承認されていない可能性があります。たとえば、認識されていないバージョンの Android を搭載している、ブートローダーがロック解除されている、メーカーによる認定を受けていない、などの場合があります。
MEETS_STRONG_INTEGRITY
- アプリは、Google Play 開発者サービスを搭載した Android デバイスで動作しており、システム完全性の強力な保証(ハードウェア格納型のブート完全性保証など)が存在します。このデバイスはシステム完全性チェックに合格し、Android の互換性要件を満たしています。
ラベルのそれぞれの条件が満たされている場合、1 つのデバイスがデバイスの完全性判定の結果で複数のデバイスラベルを返します。
最近のデバイスのアクティビティ
最近のデバイスのアクティビティをオプトインすることもできます。これにより、過去 1 時間にアプリが特定のデバイスで完全性トークンをリクエストした回数を確認できます。最近のデバイスのアクティビティを使用することで、予期せぬ不審なアクティビティを過剰に行っている(アクティブな攻撃を示している可能性がある)デバイスからアプリを保護できます。一般的なデバイスにインストールされたアプリが 1 時間ごとに完全性トークンをリクエストする回数の予測に基づいて、最近のデバイスのアクティビティの信頼レベルを決定できます。
recentDeviceActivity
を受け取ることをオプトインした場合、deviceIntegrity
フィールドには以下の 2 つの値が含まれるようになります。
deviceIntegrity: { deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"] recentDeviceActivity: { // "LEVEL_2" is one of several possible values. deviceActivityLevel: "LEVEL_2" } }
deviceActivityLevel
の定義はモードによって異なり、次のいずれかの値に設定できます。
最近のデバイスのアクティビティ レベル | 過去 1 時間にこのデバイスでアプリごとに行われた Standard API 完全性トークン リクエスト | 過去 1 時間にこのデバイスでアプリごとに行われたクラシック API 完全性トークン リクエスト |
---|---|---|
LEVEL_1 (最小) |
10 本以下 | 5 以下 |
LEVEL_2 |
11 ~ 25 | 6 ~ 10 人 |
LEVEL_3 |
26 ~ 50 | 11 ~ 15 |
LEVEL_4 (最高) |
50 件以上 | 16 以上 |
UNEVALUATED |
最近のデバイスのアクティビティは評価されませんでした。原因は次のとおりです。
|
デバイスの属性
デバイス属性を有効にすることもできます。デバイス属性は、デバイスで実行されている Android OS の Android SDK バージョンを示します。今後、他のデバイス属性が追加される可能性があります。
SDK バージョンの値は、Build.VERSION_CODES
で定義された Android SDK バージョン番号です。必要な要件が満たされていない場合、SDK バージョンは評価されません。この場合、sdkVersion
フィールドは設定されていないため、deviceAttributes
フィールドは空になります。以下のような原因が考えられます。
- デバイスの信頼性が十分でない。
- デバイスにインストールされているアプリのバージョンが Google Play に認識されていない。
- デバイスで技術的な問題が発生した。
deviceAttributes
を受け取ることをオプトインすると、deviceIntegrity
フィールドに次の追加フィールドが含まれるようになります。
deviceIntegrity: { deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"] deviceAttributes: { // 33 is one possible value, which represents Android 13 (Tiramisu). sdkVersion: 33 } }
SDK バージョンが評価されていない場合、deviceAttributes
フィールドは次のように設定されます。
deviceIntegrity: { deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"] deviceAttributes: {} // sdkVersion field is not set. }
アカウントの詳細フィールド
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 Play に認識されていない。
- ユーザーが 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 プロテクトの判定結果は、デバイスで Google Play プロテクトが有効になっているか、既知のマルウェアが検出されたかどうかを示します。
Google Play Console でアプリアクセス リスクの判定結果または Play プロテクトの判定結果にオプトインしている場合は、API レスポンスに environmentDetails
フィールドが含まれます。environmentDetails
フィールドには、appAccessRiskVerdict
と playProtectVerdict
の 2 つの値を指定できます。
アプリアクセス リスクの判定結果
アカウント アクティビティを有効にすると、Play Integrity API ペイロードの environmentDetails
フィールドに、新しいアプリアクセス リスク判定結果が含まれます。
{
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
には 1 つ以上のレスポンスを含む appsDetected
フィールドが含まれます。これらのレスポンスは、検出されたアプリのインストール元に応じて、次の 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 で認識されている検証済みのユーザー補助サービスは含まれません。
- 空(空の値)
必要な要件が満たされていない場合、アプリアクセス リスクは評価されません。この場合、
appAccessRiskVerdict
フィールドは空です。次のような原因が考えられます。- デバイスの信頼性が十分でない。
- デバイスのフォーム ファクタがスマートフォン、タブレット、折りたたみ式ではない。
- デバイスで Android 6(API レベル 23)以降を実行していない。
- デバイスにインストールされているアプリのバージョンが Google Play に認識されていない。
- デバイス上の Google Play ストアのバージョンが古い。
- ゲームのみ: ユーザー アカウントにゲームの Play ライセンスがない。
verdictOptOut
パラメータを使用して標準リクエストが使用されました。- 標準リクエストのアプリアクセス リスクをまだサポートしていないバージョンの Play Integrity API ライブラリで標準リクエストが使用されています。
アプリアクセス リスクでは、Google Play のユーザー補助機能に関する高度な審査を経た検証済みのユーザー補助サービスは、(デバイス上の任意のアプリストアによってインストールされたもの)自動的に除外されます。「除外」とは、デバイスで実行されている検証済みユーザー補助サービスが、アプリアクセス リスク判定でキャプチャ、制御、オーバーレイのレスポンスを返さないことを意味します。ユーザー補助アプリの Google Play ユーザー補助機能に関する高度な審査をリクエストするには、アプリのマニフェストで isAccessibilityTool
フラグを true に設定して Google Play に公開するか、審査をリクエストします。
次の表に、判定結果の例とその意味を示します(この表は可能な結果をすべて挙げたものではありません)。
アプリアクセス リスク判定結果のレスポンス例 | 解釈 |
---|---|
appsDetected: ["KNOWN_INSTALLED"]
|
Google Play で認識されているインストール済みアプリ、またはデバイス メーカーによってシステム パーティションにプリロードされているアプリのみがあります。 CAPTURING、CONTROLLING、OVERLAY という判定結果となるアプリは実行されていません。 |
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 プロテクトの判定結果
有効にすると、Play Integrity API ペイロードの environmentDetails
フィールドに、Play プロテクトの判定結果が含まれます。
environmentDetails: {
playProtectVerdict: "NO_ISSUES"
}
playProtectVerdict
の値は次のいずれかになります。
NO_ISSUES
- Play プロテクトはオンになっていますが、デバイスにおいてアプリの問題は検知されませんでした。
NO_DATA
- Play プロテクトはオンになっていますが、まだスキャンが実行されていません。デバイスまたは Play ストア アプリが最近リセットされた可能性があります。
POSSIBLE_RISK
- Play プロテクトがオフになっています。
MEDIUM_RISK
- Play プロテクトがオンになっており、有害な可能性があるアプリがデバイスにインストールされていることが検知されました。
HIGH_RISK
- Play プロテクトがオンになっており、危険なアプリがデバイスにインストールされていることが検知されました。
UNEVALUATED
Play プロテクトの判定結果は評価されませんでした。
次のような原因が考えられます。
- デバイスの信頼性が十分でない。
- ゲームのみ: ユーザー アカウントにゲームの Play ライセンスがない。
Play プロテクトの判定結果の使用に関するガイダンス
アプリのバックエンド サーバーは、リスク許容度に基づいて、判定結果に基づく処理方法を決定できます。推奨される使い方と、考えられるユーザーの操作には次のようなものがあります。
NO_ISSUES
- Play プロテクトがオンになっていて、問題は検出されていないため、ユーザーの操作は必要ありません。
POSSIBLE_RISK
とNO_DATA
- この判定結果を受け取ったら、Play プロテクトがオンになっていてスキャンが実行されているか確認するようユーザーに依頼します。
NO_DATA
はまれにしか表示されません。 MEDIUM_RISK
とHIGH_RISK
- リスク許容度に応じて、Play プロテクトを起動し、Play プロテクトの警告に対応するようユーザーに依頼できます。ユーザーがこれらの要件を満たすことができない場合は、サーバー アクションからブロックできます。