Başlayın

Google AB Kullanıcı Rızası Politikası uyarınca, Birleşik Krallık ile birlikte Avrupa Ekonomik Alanı'ndaki (AEA) kullanıcılarınıza belirli açıklamalar yapmanız ve yasal olarak gerekli olduğu durumlarda çerez veya başka yerel depolama bilgilerinin kullanımının yanı sıra reklam yayınlamak amacıyla kişisel verileri (AdID gibi) kullanmak için kullanıcıların iznini almanız gerekir. Bu politika AB eGizlilik Yönergesi ve Genel Veri Koruma Yönetmeliği (GDPR) gereksinimlerini yansıtmaktadır.

Google, yayıncıları bu politika kapsamındaki gereksinimleri yerine getirmeleri konusunda desteklemek için Kullanıcı Mesajlaşma Platformu (UMP) SDK'sını sunmaktadır. UMP SDK'sı, en son IAB standartlarını destekleyecek şekilde güncellenmiştir. Artık tüm bu yapılandırmalar AdMob gizlilik ve mesajlaşma bölümünden kolayca yönetilebilir.

Ön koşullar

  • Android API level 21 veya üstü (Android için)

Mesaj türü oluşturma

Kullanıcı mesajlarını, AdMob hesabınızın Gizlilik ve mesajlaşma sekmesindeki kullanılabilir kullanıcı mesajı türlerinden birini kullanarak oluşturun. UMP SDK'sı, projenizde ayarlanan uygulama kimliğinden oluşturulan AdMob kullanıcı mesajı göstermeye çalışır. Uygulamanız için herhangi bir mesaj yapılandırılmazsa SDK bir hata döndürür.

Daha fazla bilgi için Gizlilik ve mesajlaşma hakkında bölümüne göz atın.

SDK'yı yükleyin

  1. Google Mobile Ads (GMA) C++ SDK'sını yükleme adımlarını uygulayın. UMP C++ SDK'sı, GMA C++ SDK'sına dahildir.

  2. Devam etmeden önce projede uygulamanızın AdMob uygulama kimliğini yapılandırdığınızdan emin olun.

  3. Kodunuzda, ConsentInfo::GetInstance() çağrısı yaparak UMP SDK'sını başlatın.

    • Android'de, NDK tarafından sağlanan JNIEnv ve Activity belgelerini geçmeniz gerekir. Bunu yalnızca GetInstance() numaralı telefonu ilk kez aradığınızda yapmanız gerekir.
    • Alternatif olarak, uygulamanızda zaten Firebase C++ SDK'sını kullanıyorsanız GetInstance() öğesini ilk kez çağırırken firebase::App iletebilirsiniz.
    #include "firebase/gma/ump.h"
    
    namespace ump = ::firebase::gma::ump;
    
    // Initialize using a firebase::App
    void InitializeUserMessagingPlatform(const firebase::App& app) {
      ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance(app);
    }
    
    // Initialize without a firebase::App
    #ifdef ANDROID
    void InitializeUserMessagingPlatform(JNIEnv* jni_env, jobject activity) {
      ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance(jni_env, activity);
    }
    #else  // non-Android
    void InitializeUserMessagingPlatform() {
      ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
    }
    #endif
    

ConsentInfo::GetInstance() için yapılan sonraki çağrıların tümü aynı örneği döndürür.

UMP SDK'sını kullanmayı tamamladıysanız ConsentInfo örneğini silerek SDK'yı kapatabilirsiniz:

void ShutdownUserMessagingPlatform() {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
  delete consent_info;
}

Eşzamansız işlemleri izlemek için bir Future kullanın

firebase::Future, eşzamansız yöntem çağrılarının tamamlanma durumunu belirleyebilmenizi sağlayan bir yöntem sunar.

Eşzamansız olarak bir Future döndüren ve aynı zamanda en son işlemden Future öğesini almak için bir "son sonuç" işlevi sağlayan tüm UMP C++ işlevleri ve yöntem çağrıları.

Future öğesinden sonuç almanın iki yolu vardır:

  1. İşlem tamamlandığında çağrılan kendi geri çağırma işlevinizi ileterek OnCompletion() işlevini çağırın.
  2. Future status() özelliğini düzenli olarak kontrol edin. kFutureStatusPending olan durum kFutureStatusCompleted olarak değiştiğinde işlem tamamlanmış olur.

Eşzamansız işlem tamamlandıktan sonra işlemin hata kodunu almak için Future error() politikasını kontrol etmeniz gerekir. Hata kodu 0 (kConsentRequestSuccess veya kConsentFormSuccess) ise işlem başarıyla tamamlanmıştır. Aksi takdirde hata kodunu veerror_message() hata kodunu kontrol ederek sorunun ne olduğunu belirleyin.

Tamamlama geri çağırması

Aşağıda, eşzamansız işlem tamamlandığında çağrılan bir tamamlama geri çağırması ayarlamak için OnCompletion öğesinin nasıl kullanılacağına dair bir örnek verilmiştir.

void MyApplicationStart() {
  // [... other app initialization code ...]

  ump::ConsentInfo *consent_info = ump::ConsentInfo::GetInstance();

  // See the section below for more information about RequestConsentInfoUpdate.
  firebase::Future<void> result = consent_info->RequestConsentInfoUpdate(...);

  result.OnCompletion([](const firebase::Future<void>& req_result) {
    if (req_result.error() == ump::kConsentRequestSuccess) {
      // Operation succeeded. You can now call LoadAndShowConsentFormIfRequired().
    } else {
      // Operation failed. Check req_result.error_message() for more information.
    }
  });
}

Döngü yoklamayı güncelle

Bu örnekte, uygulama başlatma sırasında eşzamansız bir işlem başlatıldıktan sonra sonuçlar, oyunun güncelleme döngüsü işlevinde (kare başına bir kez çalışan) başka bir yerde kontrol edilir.

ump::ConsentInfo *g_consent_info = nullptr;
bool g_waiting_for_request = false;

void MyApplicationStart() {
  // [... other app initialization code ...]

  g_consent_info = ump::ConsentInfo::GetInstance();
  // See the section below for more information about RequestConsentInfoUpdate.
  g_consent_info->RequestConsentInfoUpdate(...);
  g_waiting_for_request = true;
}

// Elsewhere, in the game's update loop, which runs once per frame:
void MyGameUpdateLoop() {
  // [... other game logic here ...]

  if (g_waiting_for_request) {
    // Check whether RequestConsentInfoUpdate() has finished.
    // Calling "LastResult" returns the Future for the most recent operation.
    firebase::Future<void> result =
      g_consent_info->RequestConsentInfoUpdateLastResult();

    if (result.status() == firebase::kFutureStatusComplete) {
      g_waiting_for_request = false;
      if (result.error() == ump::kConsentRequestSuccess) {
        // Operation succeeded. You can call LoadAndShowConsentFormIfRequired().
      } else {
        // Operation failed. Check result.error_message() for more information.
      }
    }
  }
}

firebase::Future hakkında daha fazla bilgi için Firebase C++ SDK belgelerine ve GMA C++ SDK belgelerine bakın.

Her uygulama lansmanında RequestConsentInfoUpdate()kullanarak kullanıcının izin bilgilerinin güncellenmesini istemeniz gerekir. Bu durum, kullanıcınızın henüz yapmadıysa izin vermesi gerekip gerekmediğini veya izin süresinin dolup dolmadığını belirler.

#include "firebase/gma/ump.h"

namespace ump = ::firebase::gma::ump;

void MyApplicationStart() {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();

  // Create a ConsentRequestParameters struct.
  ump::ConsentRequestParameters params;
  // Set tag for under age of consent. False means users are NOT under age
  // of consent.
  params.tag_for_under_age_of_consent = false;

  consent_info->RequestConsentInfoUpdate(params).OnCompletion(
    [](const Future<void>& result) {
      if (result.error() != ump::kConsentRequestSuccess) {
        LogMessage("Error requesting consent update: %s", result.error_message());
      } else {
        // Consent status is now available.
      }
    });
}

Tamamlama geri çağırması yerine güncelleme döngüsü yoklamayı kullanarak işlemin tamamlandığını kontrol etmeyle ilgili bir örnek için yukarıya bakın.

İzin formunu yükleme ve gerekirse gösterme

En güncel izin durumunu aldıktan sonra izin formu yüklemek içinConsentInfo sınıftanLoadAndShowConsentFormIfRequired() numaralı telefonu arayın. İzin durumu gerekiyorsa SDK bir form yükler ve sağlanan FormParentaracından hemen sunar. Form kapatıldıktan sonra Future tamamlandığında yapılır. İzin gerekli değilse Future hemen çağrılır.

void MyApplicationStart(ump::FormParent parent) {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();

  // Create a ConsentRequestParameters struct..
  ump::ConsentRequestParameters params;
  // Set tag for under age of consent. False means users are NOT under age of consent.
  params.tag_for_under_age_of_consent = false;

  consent_info->RequestConsentInfoUpdate(params).OnCompletion(
    [*](const Future<void>& req_result) {
      if (req_result.error() != ump::kConsentRequestSuccess) {
        // req_result.error() is a kConsentRequestError enum.
        LogMessage("Error requesting consent update: %s", req_result.error_message());
      } else {
        consent_info->LoadAndShowConsentFormIfRequired(parent).OnCompletion(
        [*](const Future<void>& form_result) {
          if (form_result.error() != ump::kConsentFormSuccess) {
            // form_result.error() is a kConsentFormError enum.
            LogMessage("Error showing consent form: %s", form_result.error_message());
          } else {
            // Either the form was shown and completed by the user, or consent was not required.
          }
        });
      }
    });
}

Kullanıcı bir seçim yaptıktan veya formu kapattıktan sonra herhangi bir işlem gerçekleştirmeniz gerekirse bu mantığı, LoadAndShowConsentFormIfRequired() tarafından döndürülen Future işlemini işleyen koda yerleştirin.

Reklam isteğinde bulun

Uygulamanızda reklam isteğinde bulunmadan önce, ConsentInfo::GetInstance()‑>CanRequestAds()özelliğini kullanarak kullanıcıdan izin alıp almadığınızı kontrol edin. İzin alırken kontrol edilecek iki yer vardır:

  1. Geçerli oturumda izin alındıktan sonra.
  2. RequestConsentInfoUpdate()numaralı telefonu aradıktan hemen sonra. Önceki oturumda izin alınmış olabilir. Gecikmeye yönelik en iyi uygulama olarak, geri çağırmanın tamamlanmasını beklememenizi öneririz. Böylece uygulamanız kullanıma sunulduktan sonra mümkün olan en kısa sürede reklam yüklemeye başlayabilirsiniz.

İzin toplama sürecinde bir hata oluşursa yine de reklam istemeyi denemeniz gerekir. UMP SDK'sı, önceki oturumdaki izin durumunu kullanır.

Aşağıdaki eksiksiz örnek, güncelleme döngüsü yoklamayı kullanır ancak eşzamansız işlemleri izlemek için OnCompletion geri çağırmaları da kullanabilirsiniz. Kod yapınıza en uygun tekniği kullanın.

#include "firebase/future.h"
#include "firebase/gma/gma.h"
#include "firebase/gma/ump.h"

namespace gma = ::firebase::gma;
namespace ump = ::firebase::gma::ump;
using firebase::Future;

ump::ConsentInfo* g_consent_info = nullptr;
// State variable for tracking the UMP consent flow.
enum { kStart, kRequest, kLoadAndShow, kInitGma, kFinished, kErrorState } g_state = kStart;
bool g_ads_allowed = false;

void MyApplicationStart() {
  g_consent_info = ump::ConsentInfo::GetInstance(...);

  // Create a ConsentRequestParameters struct..
  ump::ConsentRequestParameters params;
  // Set tag for under age of consent. False means users are NOT under age of consent.
  params.tag_for_under_age_of_consent = false;

  g_consent_info->RequestConsentInfoUpdate(params);
  // CanRequestAds() can return a cached value from a previous run immediately.
  g_ads_allowed = g_consent_info->CanRequestAds();
  g_state = kRequest;
}

// This function runs once per frame.
void MyGameUpdateLoop() {
  // [... other game logic here ...]

  if (g_state == kRequest) {
    Future<void> req_result = g_consent_info->RequestConsentInfoUpdateLastResult();

    if (req_result.status() == firebase::kFutureStatusComplete) {
      g_ads_allowed = g_consent_info->CanRequestAds();
      if (req_result.error() == ump::kConsentRequestSuccess) {
        // You must provide the FormParent (Android Activity or iOS UIViewController).
        ump::FormParent parent = GetMyFormParent();
        g_consent_info->LoadAndShowConsentFormIfRequired(parent);
        g_state = kLoadAndShow;
      } else {
        LogMessage("Error requesting consent status: %s", req_result.error_message());
        g_state = kErrorState;
      }
    }
  }
  if (g_state == kLoadAndShow) {
    Future<void> form_result = g_consent_info->LoadAndShowConsentFormIfRequiredLastResult();

    if (form_result.status() == firebase::kFutureStatusComplete) {
      g_ads_allowed = g_consent_info->CanRequestAds();
      if (form_result.error() == ump::kConsentRequestSuccess) {
        if (g_ads_allowed) {
          // Initialize GMA. This is another asynchronous operation.
          firebase::gma::Initialize();
          g_state = kInitGma;
        } else {
          g_state = kFinished;
        }
        // Optional: shut down the UMP SDK to save memory.
        delete g_consent_info;
        g_consent_info = nullptr;
      } else {
        LogMessage("Error displaying consent form: %s", form_result.error_message());
        g_state = kErrorState;
      }
    }
  }
  if (g_state == kInitGma && g_ads_allowed) {
    Future<gma::AdapterInitializationStatus> gma_future = gma::InitializeLastResult();

    if (gma_future.status() == firebase::kFutureStatusComplete) {
      if (gma_future.error() == gma::kAdErrorCodeNone) {
        g_state = kFinished;
        // TODO: Request an ad.
      } else {
        LogMessage("Error initializing GMA: %s", gma_future.error_message());
        g_state = kErrorState;
      }
    }
  }
}

Gizlilik seçenekleri

Bazı izin formları, kullanıcının dilediği zaman iznini değiştirmesini gerektirir. Gerekirse gizlilik seçenekleri düğmesi uygulamak için aşağıdaki adımları uygulayın.

Bunu yapabilmek için:

  1. Uygulamanızın ayarlar sayfasındaki bir düğme gibi gizlilik seçenekleri formunu tetikleyebilecek bir kullanıcı arayüzü öğesi uygulayın.
  2. İşlem tamamlandığında, gizlilik seçenekleri formunu sunabilecek kullanıcı arayüzü öğesinin gösterilip gösterilmeyeceğini belirlemek içingetPrivacyOptionsRequirementStatus() işaretini işaretleyin. LoadAndShowConsentFormIfRequired()
  3. Kullanıcı arayüzü öğenizle etkileşimde bulunan bir kullanıcı, gizlilik seçeneklerini dilediği zaman güncelleyebilmesi için formu göstermek üzereshowPrivacyOptionsForm() numaralı telefonu arayın.

Test

Uygulamanız geliştirme aşamasındayken entegrasyonu test etmek isterseniz test cihazınızı programatik olarak kaydetmek için bu adımları uygulayın. Uygulamanızı yayınlamadan önce bu test cihazı kimliklerini ayarlayan kodu kaldırdığınızdan emin olun.

  1. RequestConsentInfoUpdate()numaralı telefonu arayın.
  2. Günlük çıktısında, cihaz kimliğinizi ve test cihazı olarak nasıl ekleyeceğinizi gösteren aşağıdaki örneğe benzer bir mesaj olup olmadığını kontrol edin:

    Android

    Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231")
    to set this as a debug device.
    

    iOS

    <UMP SDK>To enable debug mode for this device,
    set: UMPDebugSettings.testDeviceIdentifiers = @[2077ef9a63d2b398840261c8221a0c9b]
    
  3. Test cihazı kimliğinizi panonuza kopyalayın.

  4. Kodunuzu, test cihazı kimliklerinizin listesini çağıracakConsentRequestParameters.debug_settings.debug_device_ids ve şekilde değiştirin.

    void MyApplicationStart() {
      ump::ConsentInfo consent_info = ump::ConsentInfo::GetInstance(...);
    
      ump::ConsentRequestParameters params;
      params.tag_for_under_age_of_consent = false;
      params.debug_settings.debug_device_ids = {"TEST-DEVICE-HASHED-ID"};
    
      consent_info->RequestConsentInfoUpdate(params);
    }
    

Coğrafi konumu zorunlu kılın

UMP SDK'sı, ConsentRequestParameters.debug_settings.debug_geographykullanılarak cihaz AEA veya Birleşik Krallık'ta bulunuyormuş gibi uygulamanızın davranışını test edebileceğiniz bir yöntem sunar. Hata ayıklama ayarlarının yalnızca test cihazlarında çalıştığını unutmayın.

void MyApplicationStart() {
  ump::ConsentInfo consent_info = ump::ConsentInfo::GetInstance(...);

  ump::ConsentRequestParameters params;
  params.tag_for_under_age_of_consent = false;
  params.debug_settings.debug_device_ids = {"TEST-DEVICE-HASHED-ID"};
  // Geography appears as EEA for debug devices.
  params.debug_settings.debug_geography = ump::kConsentDebugGeographyEEA

  consent_info->RequestConsentInfoUpdate(params);
}

Uygulamanızı UMP SDK ile test ederken bir kullanıcının ilk yükleme deneyimini simüle edebilmek için SDK'nın durumunu sıfırlamayı yararlı bulabilirsiniz. SDK, bunun için Reset() yöntemini sunar.

  ConsentInfo::GetInstance()->Reset();