Đạt được sự đồng ý với Nền tảng nhắn tin của người dùng

Điều kiện tiên quyết

Hãy đọc Các yêu cầu của IAB ảnh hưởng như thế nào đến thông báo yêu cầu đồng ý ở Liên minh Châu Âu.

Giới thiệu

Theo Chính sách về sự đồng ý của người dùng ở Liên minh Châu Âu của Google, bạn phải công bố một số thông tin nhất định cho người dùng ở Khu vực kinh tế Châu Âu (EEA) cùng với Vương quốc Anh và xin phép họ sử dụng cookie hoặc bộ nhớ cục bộ khác (nếu pháp luật yêu cầu) và sử dụng dữ liệu cá nhân (chẳng hạn như AdID) để phân phát quảng cáo. Chính sách này phản ánh các yêu cầu của Chỉ thị về quyền riêng tư và truyền thông điện tử của Liên minh Châu Âu và Quy định chung về việc bảo vệ dữ liệu (GDPR).

Để hỗ trợ nhà xuất bản đáp ứng các nghĩa vụ của họ theo chính sách này, Google cung cấp SDK Nền tảng thông báo cho người dùng (UMP), thay thế cho SDK lấy sự đồng ý nguồn mở trước đó. SDK UMP đã được cập nhật để hỗ trợ các tiêu chuẩn IAB mới nhất. Chúng tôi cũng đã đơn giản hoá quy trình thiết lập biểu mẫu lấy sự đồng ý và liệt kê các đối tác quảng cáo. Hiện tại, tất cả các cấu hình này có thể được xử lý một cách thuận tiện trong Quyền riêng tư và amp; AdMob; nhắn tin.

Phương pháp hay nhất là tải biểu mẫu mỗi khi người dùng chạy ứng dụng, ngay cả khi bạn xác định rằng không cần sự đồng ý để biểu mẫu sẵn sàng hiển thị trong trường hợp người dùng muốn thay đổi chế độ cài đặt về sự đồng ý.

Hướng dẫn này trình bày cách cài đặt SDK, triển khai các giải pháp IAB và bật các tính năng thử nghiệm.

Cài đặt bằng Gradle

Đưa thư viện vào tệp build.gradle của ứng dụng:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'com.google.android.ump:user-messaging-platform:2.0.0'
}

Đừng quên đồng bộ hoá Gradle khi bạn hoàn tất.

Thêm mã ứng dụng vào AndroidManifest.xml

Lấy mã ứng dụng của bạn bằng cách làm theo hướng dẫn trong Trung tâm trợ giúp.

Thêm mã ứng dụng của bạn vào AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rewardedinterstitialexample">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="YOUR-APP-ID"/>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Sử dụng SDK

SDK này được thiết kế để sử dụng theo kiểu tuyến tính. Các bước để sử dụng SDK là:

  1. Yêu cầu thông tin về sự đồng ý mới nhất.
  2. Kiểm tra xem bạn có cần sự đồng ý không.
  3. Kiểm tra xem có biểu mẫu nào không và nếu có, hãy tải biểu mẫu.
  4. Trình bày biểu mẫu.
  5. Cung cấp cho người dùng một cách để thay đổi sự đồng ý của họ.

Bạn nên yêu cầu cập nhật thông tin về sự đồng ý vào mỗi lần khởi chạy ứng dụng. Mục này sẽ xác định xem người dùng có cần đồng ý hay không.

Java

import android.os.Bundle;
import com.google.android.ump.ConsentForm;
import com.google.android.ump.ConsentInformation;
import com.google.android.ump.ConsentRequestParameters;
import com.google.android.ump.FormError;
import com.google.android.ump.UserMessagingPlatform;

public class MainActivity extends AppCompatActivity {
  private ConsentInformation consentInformation;
  private ConsentForm consentForm;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set tag for underage of consent. Here false means users are not underage.
    ConsentRequestParameters params = new ConsentRequestParameters
        .Builder()
        .setTagForUnderAgeOfConsent(false)
        .build();

    consentInformation = UserMessagingPlatform.getConsentInformation(this);
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        new ConsentInformation.OnConsentInfoUpdateSuccessListener() {
          @Override
          public void onConsentInfoUpdateSuccess() {
            // The consent information state was updated.
            // You are now ready to check if a form is available.
          }
        },
        new ConsentInformation.OnConsentInfoUpdateFailureListener() {
          @Override
          public void onConsentInfoUpdateFailure(FormError formError) {
            // Handle the error.
          }
        });
  }
}

Kotlin

import android.os.Bundle
import com.google.android.ump.*

class MainActivity : AppCompactActivity() {
  private lateinit var consentInformation: ConsentInformation
  private var consentForm: ConsentForm? = null

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Set tag for underage of consent. Here false means users are not underage.
    val params = ConsentRequestParameters.Builder()
        .setTagForUnderAgeOfConsent(false)
        .build()

    consentInformation = UserMessagingPlatform.getConsentInformation(this)
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        {
          // The consent information state was updated.
          // You are now ready to check if a form is available.
        },
        { formError ->
          // Handle the error.
        }
    )
  }
}

Tải một biểu mẫu (nếu có)

Sau khi bạn xác định rằng sẽ yêu cầu người dùng đồng ý, bước tiếp theo là xác định xem có biểu mẫu nào không.

Có nhiều lý do khiến biểu mẫu có thể không có sẵn, chẳng hạn như:

  • Người dùng đã bật tính năng theo dõi quảng cáo bị hạn chế.
  • Bạn đã gắn thẻ người dùng là dưới độ tuổi hợp pháp để tự quản lý tài khoản.

Để kiểm tra xem có biểu mẫu nào không, hãy sử dụng phương thức isConsentFormAvailable() trên thực thể ConsentInformation. Thêm phương thức trình bao bọc để tải biểu mẫu:

Java

...
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        new ConsentInformation.OnConsentInfoUpdateSuccessListener() {
          @Override
          public void onConsentInfoUpdateSuccess() {
            // The consent information state was updated.
            // You are now ready to check if a form is available.
            if (consentInformation.isConsentFormAvailable()) {
              loadForm();
            }
          }
        },
        new ConsentInformation.OnConsentInfoUpdateFailureListener() {
          @Override
          public void onConsentInfoUpdateFailure(FormError formError) {
            // Handle the error.
          }
        });
}

public void loadForm() {

}

Kotlin

...
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        {
          // The consent information state was updated.
          // You are now ready to check if a form is available.
          if (consentInformation.isConsentFormAvailable) {
            loadForm()
          }
        },
        { formError ->
          // Handle the error.
        }
    )
}

private fun loadForm() {

}

Để tải biểu mẫu, bạn sẽ sử dụng phương thức loadConsentForm() tĩnh trên lớp UserMessagingPlatform. Phương thức này chỉ được gọi từ luồng chính. Thay đổi phương thức loadForm() như sau:

Java

public void loadForm() {
  UserMessagingPlatform.loadConsentForm(
      this, new UserMessagingPlatform.OnConsentFormLoadSuccessListener() {
        @Override
        public void onConsentFormLoadSuccess(ConsentForm consentForm) {
          MainActivity.this.consentForm = consentForm;
        }
      },
      new UserMessagingPlatform.OnConsentFormLoadFailureListener() {
        @Override
        public void onConsentFormLoadFailure(FormError formError) {
          // Handle the error.
        }
      });
}

Kotlin

private fun loadForm() {
  UserMessagingPlatform.loadConsentForm(
      this,
      { consentForm ->
        this.consentForm = consentForm
      },
      { formError ->
        // Handle the error.
      }
  )
}

Trình bày biểu mẫu nếu cần

Để hiển thị biểu mẫu, hãy sử dụng phương thức show() trên thực thể ConsentForm. Bạn nên xác định xem người dùng có cần đồng ý trước khi trình bày biểu mẫu hay không. Để kiểm tra xem có cần sự đồng ý hay không, hãy kiểm tra phương thức getConsentStatus() trên đối tượng ConsentInformation, đối tượng này sẽ trả về một giá trị enum thuộc loại ConsentInformation.ConsentStatus. Có thể có bốn giá trị:

  • ConsentStatus.UNKNOWN: Trạng thái đồng ý không xác định.
  • ConsentStatus.REQUIRED: Cần có sự đồng ý của người dùng nhưng chưa nhận được.
  • ConsentStatus.NOT_REQUIRED: Không yêu cầu sự đồng ý của người dùng. Ví dụ: người dùng không ở EEA hoặc Vương quốc Anh.
  • ConsentStatus.OBTAINED: Có được sự đồng ý của người dùng. Không xác định được chế độ cá nhân hóa.

Thay đổi phương thức loadForm() như sau:

Java

public void loadForm() {
  UserMessagingPlatform.loadConsentForm(
      this, new UserMessagingPlatform.OnConsentFormLoadSuccessListener() {
        @Override
        public void onConsentFormLoadSuccess(ConsentForm consentForm) {
          MainActivity.this.consentForm = consentForm;
          if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.REQUIRED) {
            consentForm.show(
                MainActivity.this,
                    new ConsentForm.OnConsentFormDismissedListener() {
                      @Override
                      public void onConsentFormDismissed(@Nullable FormError formError) {
                        // Handle dismissal by reloading form.
                        loadForm();
                      }
                    });
          }
        }
      },
      new UserMessagingPlatform.OnConsentFormLoadFailureListener() {
        @Override
        public void onConsentFormLoadFailure(FormError formError) {
          // Handle the error.
        }
      });
}

Kotlin

private fun loadForm() {
  UserMessagingPlatform.loadConsentForm(
      this,
      { consentForm ->
        this.consentForm = consentForm
        if (consentInformation.consentStatus == ConsentInformation.ConsentStatus.REQUIRED) {
          consentForm.show(this) { formError ->
            // Handle dismissal by reloading form.
            loadForm()
          }
        }
      },
      { formError ->
        // Handle the error.
      }
  )
}

Nếu không bắt buộc phải có sự đồng ý, bạn có thể duy trì tham chiếu đến biểu mẫu đó để người dùng có thể thay đổi trạng thái đồng ý của họ.

Thử nghiệm

Buộc một khu vực địa lý

SDK UMP cung cấp một cách để kiểm tra hành vi của ứng dụng như thể thiết bị này được đặt tại Khu vực kinh tế Châu Âu (EEA) bằng cách sử dụng phương thức setDebugGeography() trên ConsentDebugSettings.Builder.

Bạn sẽ cần cung cấp mã băm của thiết bị thử nghiệm trong phần cài đặt gỡ lỗi của ứng dụng để sử dụng chức năng gỡ lỗi. Nếu bạn gọi requestConsentInfoUpdate() mà không đặt giá trị này, thì ứng dụng sẽ ghi lại hàm băm mã nhận dạng bắt buộc khi chạy.

Java

ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(this)
    .setDebugGeography(ConsentDebugSettings
        .DebugGeography
        .DEBUG_GEOGRAPHY_EEA)
    .addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
    .build();

ConsentRequestParameters params = new ConsentRequestParameters
    .Builder()
    .setConsentDebugSettings(debugSettings)
    .build();

consentInformation = UserMessagingPlatform.getConsentInformation(this);
consentInformation.requestConsentInfoUpdate(
    this,
    params,
    new ConsentInformation.OnConsentInfoUpdateSuccessListener() {
      @Override
      public void onConsentInfoUpdateSuccess() {
        // The consent information state was updated.
        // You are now ready to check if a form is available.
      }
    },
    new ConsentInformation.OnConsentInfoUpdateFailureListener() {
      @Override
      public void onConsentInfoUpdateFailure(FormError formError) {
        // Handle the error.
      }
    });

Kotlin

val debugSettings = ConsentDebugSettings.Builder(this)
    .setDebugGeography(ConsentDebugSettings
        .DebugGeography
        .DEBUG_GEOGRAPHY_EEA)
    .addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
    .build()

val params = ConsentRequestParameters
    .Builder()
    .setConsentDebugSettings(debugSettings)
    .build()

consentInformation = UserMessagingPlatform.getConsentInformation(this)
consentInformation.requestConsentInfoUpdate(
    this,
    params,
    {
      // The consent information state was updated.
      // You are now ready to check if a form is available.
    },
    { formError ->
      // Handle the error.
    }
  )

Để buộc SDK xử lý thiết bị như thể thiết bị không ở Khu vực kinh tế Châu Âu (EEA) hoặc Vương quốc Anh, hãy sử dụng DebugGeography.DEBUG_GEOGRAPHY_NOT_EEA. Lưu ý các chế độ cài đặt gỡ lỗi chỉ hoạt động trên thiết bị thử nghiệm. Bạn không cần thêm trình mô phỏng vào danh sách mã thiết bị vì trình mô phỏng đã bật tính năng kiểm thử theo mặc định.

Khi kiểm thử ứng dụng bằng SDK UMP, bạn nên đặt lại trạng thái của SDK để có thể mô phỏng trải nghiệm cài đặt đầu tiên của người dùng. SDK này cung cấp phương thức reset để thực hiện việc này.

Java

consentInformation.reset();

Kotlin

consentInformation.reset()

Trì hoãn đo lường ứng dụng (không bắt buộc)

Theo mặc định, SDK quảng cáo trên thiết bị di động của Google khởi chạy hoạt động đo lường ứng dụng và bắt đầu gửi dữ liệu sự kiện cấp người dùng tới Google ngay khi ứng dụng khởi động. Hành vi khởi chạy này đảm bảo bạn có thể bật các chỉ số người dùng AdMob mà không cần thực hiện thêm thay đổi nào về mã.

Tuy nhiên, nếu ứng dụng của bạn cần có sự đồng ý của người dùng trước khi gửi những sự kiện này, thì bạn có thể trì hoãn việc đo lường ứng dụng cho đến khi chắc chắn khởi chạy SDK quảng cáo trên thiết bị di động hoặc tải quảng cáo.

Để trì hoãn việc đo lường ứng dụng, hãy thêm thẻ <meta-data> sau vào AndroidManifest.xml.

<manifest>
     <application>
        <!-- Delay app measurement until MobileAds.initialize() is called. -->
        <meta-data
            android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT"
            android:value="true"/>
    </application>
</manifest>

Dàn xếp

Nếu sử dụng tính năng dàn xếp, bạn sẽ cần xử lý sự đồng ý cho các đối tác dàn xếp theo cách khác nhau dựa trên khuôn khổ về sự đồng ý mà bạn chọn sử dụng trên ứng dụng của mình. Google hỗ trợ Khuôn khổ về sự đồng ý của IAB nhưng cũng cho phép bạn có giải pháp đồng ý tùy chỉnh của riêng mình. Dưới đây là thông tin chi tiết về cách xử lý tính năng dàn xếp theo từng tùy chọn. Tìm hiểu thêm về giải pháp yêu cầu sự đồng ý của chúng tôi.

Cả SDK UMP và SDK quảng cáo trên thiết bị di động đều không chuyển tiếp thông tin về sự đồng ý đến các đối tác dàn xếp. Thay vào đó, khi sử dụng giải pháp IAB, SDK UMP ghi thông tin trạng thái đồng ý vào bộ nhớ cục bộ và mỗi SDK của đối tác dàn xếp có trách nhiệm đọc các khoá thích hợp. Hãy nhớ liên hệ với từng mạng bên thứ ba để xác định xem họ có hỗ trợ giải pháp của IAB không.

Nếu sử dụng một giải pháp đồng ý tuỳ chỉnh, bạn có trách nhiệm thông báo cho SDK của bên thứ ba về trạng thái đồng ý của ứng dụng. Để biết thông tin chi tiết về cách chuyển thông tin về sự đồng ý đến các bên thứ ba có liên quan, vui lòng tham khảo hướng dẫn tích hợp của từng đối tác dàn xếp để biết thông tin chi tiết về cách triển khai.

此部分中的代码可用于任何版本的 Google 移动广告 SDK。无论您是否使用 Consent SDK 征求用户意见,均可使用这些代码。

默认的 Google 移动广告 SDK 行为是投放个性化广告。如果用户仅同意接收非个性化广告,您可以配置 AdRequest 对象,以指定只应请求非个性化广告。无论用户是否在欧洲经济区 (EEA) 内,以下代码都会导致请求非个性化广告:

Bundle extras = new Bundle();
extras.putString("npa", "1");

AdRequest request = new AdRequest.Builder()
    .addNetworkExtrasBundle(AdMobAdapter.class, extras)
    .build();

如果请求的是非个性化广告,则广告请求网址目前会包含 &npa=1。但请注意,这是 Google 移动广告 SDK 的内部实现细节,随时可能会出现更改。