Doanh thu từ quảng cáo ở cấp lượt hiển thị

Khi một lượt hiển thị xảy ra, GMA Next-Gen SDK sẽ cung cấp dữ liệu doanh thu từ quảng cáo liên quan đến lượt hiển thị đó. Bạn có thể sử dụng dữ liệu này để tính toán giá trị vòng đời của người dùng hoặc chuyển dữ liệu cho các hệ thống liên quan khác.

Hướng dẫn này nhằm giúp bạn triển khai tính năng thu thập dữ liệu về doanh thu từ quảng cáo ở cấp lượt hiển thị trong ứng dụng Android.

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

Mỗi định dạng quảng cáo đều có một lệnh gọi lại sự kiện onAdPaid. Trong vòng đời của một sự kiện quảng cáo, GMA Next-Gen SDK sẽ theo dõi các sự kiện hiển thị và gọi trình xử lý bằng giá trị nhận được.

Ví dụ sau đây xử lý các sự kiện có tính phí cho một quảng cáo có tặng thưởng:

Kotlin

ad.adEventCallback =
  object : RewardedAdEventCallback {
    override fun onAdPaid(adValue: AdValue) {
      // Send the impression-level ad revenue information to your
      // preferred analytics server directly within this callback.

      // Extract the impression-level ad revenue data.
      val valueMicros = adValue.valueMicros
      val currencyCode = adValue.currencyCode
      val precisionType = adValue.precisionType

      val loadedAdSourceResponseInfo = ad.getResponseInfo().loadedAdSourceResponseInfo
      val adSourceName = loadedAdSourceResponseInfo?.name
      val adSourceId = loadedAdSourceResponseInfo?.id
      val adSourceInstanceName = loadedAdSourceResponseInfo?.instanceName
      val adSourceInstanceId = loadedAdSourceResponseInfo?.instanceId
      val extras = ad.getResponseInfo().responseExtras
      val mediationGroupName = extras.getString("mediation_group_name")
      val mediationABTestName = extras.getString("mediation_ab_test_name")
      val mediationABTestVariant = extras.getString("mediation_ab_test_variant")
    }
  }

Java

ad.setAdEventCallback(
    new RewardedAdEventCallback() {
      @Override
      public void onAdPaid(@NonNull AdValue value) {
        // Send the impression-level ad revenue information to your preferred
        // analytics server directly within this callback.

        // Extract the impression-level ad revenue data.
        long valueMicros = value.getValueMicros();
        String currencyCode = value.getCurrencyCode();
        PrecisionType precisionType = value.getPrecisionType();

        AdSourceResponseInfo loadedAdSourceResponseInfo =
            ad.getResponseInfo().getLoadedAdSourceResponseInfo();
        String adSourceName = loadedAdSourceResponseInfo.getName();
        String adSourceId = loadedAdSourceResponseInfo.getId();
        String adSourceInstanceName = loadedAdSourceResponseInfo.getInstanceName();
        String adSourceInstanceId = loadedAdSourceResponseInfo.getInstanceId();

        Bundle extras = ad.getResponseInfo().getResponseExtras();
        String mediationGroupName = extras.getString("mediation_group_name");
        String mediationABTestName = extras.getString("mediation_ab_test_name");
        String mediationABTestVariant = extras.getString("mediation_ab_test_variant");
      }
    });

Xác định tên nguồn quảng cáo của sự kiện tuỳ chỉnh

Đối với nguồn quảng cáo sự kiện tuỳ chỉnh, thuộc tính AdSourceResponseInfo.name sẽ trả về tên nguồn quảng cáo Custom event. Nếu bạn sử dụng nhiều sự kiện tuỳ chỉnh, thì tên nguồn quảng cáo sẽ không đủ chi tiết để phân biệt giữa nhiều sự kiện tuỳ chỉnh. Để xác định vị trí của một sự kiện tuỳ chỉnh cụ thể, hãy làm như sau:

  1. Lấy thuộc tính AdSourceResponseInfo.name.
  2. Đặt một tên riêng biệt cho nguồn quảng cáo.

Ví dụ sau đây đặt một tên nguồn quảng cáo riêng biệt cho một sự kiện tuỳ chỉnh:

Kotlin

private fun getUniqueAdSourceName(loadedAdapterResponseInfo: AdSourceResponseInfo): String {
  var adSourceName = loadedAdapterResponseInfo.name
  if (adSourceName == "Custom Event") {
    if (
      loadedAdapterResponseInfo.adapterClassName ==
        "com.google.ads.mediation.sample.customevent.SampleCustomEvent"
    ) {
      adSourceName = "Sample Ad Network (Custom Event)"
    }
  }
  return adSourceName
}

Java

private String getUniqueAdSourceName(@NonNull AdSourceResponseInfo loadedAdapterResponseInfo) {
  String adSourceName = loadedAdapterResponseInfo.getName();
  if (adSourceName.equals("Custom Event")) {
    if (loadedAdapterResponseInfo
        .getAdapterClassName()
        .equals("com.google.ads.mediation.sample.customevent.SampleCustomEvent")) {
      adSourceName = "Sample Ad Network (Custom Event)";
    }
  }
  return adSourceName;
}

Để biết thêm thông tin về nguồn quảng cáo giành chiến thắng, hãy xem bài viết Truy xuất thông tin về lượt phản hồi quảng cáo.

Tích hợp với Đối tác phân bổ ứng dụng (AAP)

Để biết thông tin đầy đủ về cách chuyển dữ liệu doanh thu từ quảng cáo đến các nền tảng phân tích, hãy tham khảo hướng dẫn của đối tác:

Partner SDK
Adjust
AppsFlyer
Singular
Tenjin

Hướng dẫn dành cho đối tác có thể chưa được cập nhật để tham chiếu đến GMA Next-Gen SDK.

Các ví dụ sau đây cho thấy cách gửi dữ liệu doanh thu ở cấp lượt hiển thị cho các đối tác AAP bằng cách sử dụng GMA Next-Gen SDK:

Điều chỉnh

Java

rewardedAd.setAdEventCallback(
    new RewardedAdEventCallback() {
      @Override
      public void onAdPaid(@NonNull AdValue value) {
        // Send ad revenue info to Adjust.
        AdjustAdRevenue adRevenue = new AdjustAdRevenue("admob_sdk");
        adRevenue.setRevenue(value.getValueMicros() / 1000000.0, value.getCurrencyCode());
        if (rewardedAd.getResponseInfo().getLoadedAdSourceResponseInfo() != null) {
          adRevenue.setAdRevenueNetwork(
              rewardedAd.getResponseInfo().getLoadedAdSourceResponseInfo().getName());
        }
        Adjust.trackAdRevenue(adRevenue);
      }
    });

Kotlin

rewardedAd.adEventCallback =
  object : RewardedAdEventCallback {
    override fun onAdPaid(value: AdValue) {
      // Send ad revenue info to Adjust.
      val adRevenue = AdjustAdRevenue("admob_sdk")
      adRevenue.setRevenue(value.valueMicros / 1000000.0, value.currencyCode)
      val loadedAdSourceResponseInfo = rewardedAd.getResponseInfo().loadedAdSourceResponseInfo
      loadedAdSourceResponseInfo?.let { adRevenue.setAdRevenueNetwork(it.name) }
      Adjust.trackAdRevenue(adRevenue)
    }
  }

AppsFlyer

Java

rewardedAd.setAdEventCallback(
    new RewardedAdEventCallback() {
      @Override
      public void onAdPaid(@NonNull AdValue value) {
        long valueMicros = value.getValueMicros();
        String currencyCode = value.getCurrencyCode();

        AFAdRevenueData adRevenueData =
            new AFAdRevenueData(
                "AdMob Mediation", // monetizationNetwork
                MediationNetwork.GOOGLE_ADMOB, // mediationNetwork
                currencyCode, // currencyIso4217Code
                (double) valueMicros // revenue
                );

        Map<String, Object> additionalParameters = new HashMap<>();
        additionalParameters.put(COUNTRY, "US");
        additionalParameters.put(AD_UNIT, AD_UNIT_ID);
        additionalParameters.put(AD_TYPE, AdFormat.REWARDED);

        AppsFlyerLib.getInstance().logAdRevenue(adRevenueData, additionalParameters);
      }
    });

Kotlin

rewardedAd.adEventCallback =
  object : RewardedAdEventCallback {
    override fun onAdPaid(value: AdValue) {
      val valueMicros = value.valueMicros
      val currencyCode = value.currencyCode

      val adRevenueData =
        AFAdRevenueData(
          "AdMob Mediation", // monetizationNetwork
          MediationNetwork.GOOGLE_ADMOB, // mediationNetwork
          currencyCode, // currencyIso4217Code
          valueMicros.toDouble(), // revenue
        )

      val additionalParameters: MutableMap<String?, Any?> = HashMap()
      additionalParameters[COUNTRY] = "US"
      additionalParameters[AD_UNIT] = AD_UNIT_ID
      additionalParameters[AD_TYPE] = AdFormat.REWARDED

      appsflyer.logAdRevenue(adRevenueData, additionalParameters)
    }
  }

Số ít

Java

rewardedAd.setAdEventCallback(
    new RewardedAdEventCallback() {
      @Override
      public void onAdPaid(@NonNull AdValue value) {
        // Convert revenue from micros to standard units.
        double revenue = value.getValueMicros() / 1000000.0;
        String currency = value.getCurrencyCode();

        // Validate ad revenue data before sending.
        if (revenue > 0 && !currency.isEmpty()) {
          SingularAdData adData = new SingularAdData("AdMob", currency, revenue);
          Singular.adRevenue(adData);
        }
      }
    });

Kotlin

rewardedAd.adEventCallback =
  object : RewardedAdEventCallback {
    override fun onAdPaid(value: AdValue) {
      // Convert revenue from micros to standard units.
      val revenue = value.valueMicros / 1000000.0
      val currency = value.currencyCode

      // Validate ad revenue data before sending.
      if (revenue > 0 && currency.isNotEmpty()) {
        val adData = SingularAdData("AdMob", currency, revenue)
        Singular.adRevenue(adData)
      }
    }
  }

Tenjin

Đối với GMA Next-Gen SDK, bạn phải tích hợp bằng cách sử dụng một đối tượng JSON. Ví dụ sau đây gửi dữ liệu doanh thu ở cấp lượt hiển thị đến Tenjin bằng cách sử dụng một đối tượng JSON:

Java

rewardedAd.setAdEventCallback(
    new RewardedAdEventCallback() {
      @Override
      public void onAdPaid(@NonNull AdValue value) {
        ResponseInfo responseInfo = rewardedAd.getResponseInfo();

        // Extract the impression-level ad revenue data.
        long valueMicros = value.getValueMicros();
        String currencyCode = value.getCurrencyCode();
        PrecisionType precisionType = value.getPrecisionType();

        JSONObject json = new JSONObject();
        try {
          json.put("ad_unit_id", AD_UNIT_ID);
          json.put("currency_code", currencyCode);
          json.put("response_id", responseInfo.getResponseId());
          json.put("value_micros", valueMicros);
          if (responseInfo.getLoadedAdSourceResponseInfo() != null) {
            json.put(
                "mediation_adapter_class_name",
                responseInfo.getLoadedAdSourceResponseInfo().getAdapterClassName());
          }
          json.put("precision_type", precisionType);

          tenjinInstance.eventAdImpressionAdMob(json);
        } catch (JSONException e) {
          // Handle error.
        }
      }
    });

Kotlin

rewardedAd.adEventCallback =
  object : RewardedAdEventCallback {
    override fun onAdPaid(value: AdValue) {
      val responseInfo = rewardedAd.getResponseInfo()

      // Extract the impression-level ad revenue data.
      val valueMicros = value.valueMicros
      val currencyCode = value.currencyCode
      val precisionType = value.precisionType

      val json = JSONObject()
      try {
        json.put("ad_unit_id", AD_UNIT_ID)
        json.put("currency_code", currencyCode)
        json.put("response_id", responseInfo.responseId)
        json.put("value_micros", valueMicros)
        responseInfo.loadedAdSourceResponseInfo?.let {
          json.put("mediation_adapter_class_name", it.adapterClassName)
        }
        json.put("precision_type", precisionType)

        tenjinInstance.eventAdImpressionAdMob(json)
      } catch (_: JSONException) {
        // Handle error.
      }
    }
  }

Các phương pháp triển khai hay nhất

  • Thiết lập trình nghe ngay sau khi bạn tạo hoặc có quyền sử dụng đối tượng quảng cáo và ngay trước khi hiển thị quảng cáo. Điều này đảm bảo rằng bạn không bỏ lỡ bất kỳ lệnh gọi lại sự kiện có tính phí nào.
  • Gửi thông tin về doanh thu từ quảng cáo ở cấp lượt hiển thị đến máy chủ phân tích ưu tiên của bạn ngay tại thời điểm lệnh gọi lại sự kiện có tính phí được gọi. Điều này đảm bảo rằng bạn không vô tình bỏ qua bất kỳ lệnh gọi lại nào và tránh tạo ra sự chênh lệch về dữ liệu.

AdValue

AdValue là một lớp đại diện cho giá trị bằng tiền mà bạn nhận được từ một quảng cáo, bao gồm mã tiền tệ của giá trị và loại độ chính xác được mã hoá như sau.

PrecisionType Mô tả
UNKNOWN Giá trị quảng cáo không xác định. Hệ thống sẽ trả về kết quả này khi bạn bật tính năng pingback LTV, nhưng không có đủ dữ liệu.
ESTIMATED Giá trị quảng cáo được ước tính từ dữ liệu tổng hợp.
PUBLISHER_PROVIDED Nhà xuất bản đã cung cấp giá trị quảng cáo (chẳng hạn như CPM thủ công) trong một nhóm dàn xếp.
PRECISE Giá trị chính xác mà bạn phải trả cho quảng cáo này.

Trong trường hợp Dàn xếp AdMob, AdMob sẽ tìm cách cung cấp giá trị ESTIMATED cho những nguồn quảng cáo được tối ưu hoá. Đối với những nguồn quảng cáo không được tối ưu hoá, hoặc trong trường hợp không có đủ dữ liệu tổng hợp để báo cáo một giá trị ước tính có ý nghĩa, thì giá trị PUBLISHER_PROVIDED sẽ được trả về.

Lượt hiển thị thử nghiệm từ các nguồn quảng cáo đặt giá thầu

Sau khi sự kiện doanh thu từ quảng cáo ở cấp lượt hiển thị xảy ra cho một nguồn quảng cáo đặt giá thầu thông qua một yêu cầu kiểm thử, bạn sẽ chỉ nhận được các giá trị sau:

  • UNKNOWN: cho biết loại độ chính xác.
  • 0: cho biết giá trị quảng cáo.

Trước đây, bạn có thể thấy loại độ chính xác là một giá trị khác với UNKNOWN và giá trị quảng cáo lớn hơn 0.

Để biết thông tin chi tiết về cách gửi yêu cầu quảng cáo kiểm thử, hãy xem phần Bật thiết bị kiểm thử.