تضمين إعلانات في وضع "نافذة ضمن النافذة" (إصدار تجريبي)

نافذة ضمن النافذة

تظهر إعلانات "نافذة ضمن النافذة" في نافذة عائمة تبقى في أعلى المحتوى على الشاشة، مثل المقالات أو الخلاصات أو طريقة اللعب. يسمح هذا الشكل للمستخدمين بالتفاعل مع تطبيقك بينما يظلّ الإعلان مرئيًا. لاختيار عرض الإعلانات التي لا تشغل الشاشة بأكملها، يمكنك اختيار هذا الشكل.

يغطّي هذا الدليل طلب إعلانات "نافذة ضمن النافذة" وعرضها في تطبيقك باستخدام GMA Next-Gen SDK.

قبل البدء

قبل المتابعة، يُرجى اتّخاذ الإجراءات التالية:

تحميل إعلان

لتحميل PictureInPictureAd، يجب إنشاء طلب عرض الإعلان واستدعاء طريقة load:

Kotlin

private fun loadPictureInPictureAd() {
  val request = PictureInPictureAdRequest.Builder(AD_UNIT_ID).build()

  PictureInPictureAd.load(
    request,
    object : AdLoadCallback<PictureInPictureAd> {
      override fun onAdFailedToLoad(adError: LoadAdError) {
        Log.w(TAG, "Picture-in-Picture ad failed to load: $adError")
      }

      override fun onAdLoaded(ad: PictureInPictureAd) {
        Log.d(TAG, "Picture-in-Picture ad loaded.")

        // Capture the PictureInPictureAd reference for later use.
        pipAd = ad
        setAdEventCallback(ad)
      }
    },
  )
}

جافا

private void loadPictureInPictureAd() {
  PictureInPictureAdRequest request = new PictureInPictureAdRequest.Builder(AD_UNIT_ID).build();

  PictureInPictureAd.load(
      request,
      new AdLoadCallback<PictureInPictureAd>() {
        @Override
        public void onAdFailedToLoad(@NonNull LoadAdError adError) {
          Log.w(TAG, "Picture-in-Picture ad failed to load: " + adError);
        }

        @Override
        public void onAdLoaded(@NonNull PictureInPictureAd ad) {
          Log.d(TAG, "Picture-in-Picture ad loaded.");

          // Capture the PictureInPictureAd reference for later use.
          pipAd = ad;
          setAdEventCallback(ad);
        }
      });
}

يُرجى استبدال AD_UNIT_ID برقم تعريف الوحدة الإعلانية.

عرض الإعلان

لعرض إعلان "نافذة ضمن النافذة" على الشاشة، يجب ضبط خيارات "نافذة ضمن النافذة" واستدعاء طريقة show. يضبط المثال التالي الموضع التلقائي للإعلان ونطاق العرض على الشاشة:

Kotlin

private fun showPictureInPictureAd(activity: Activity) {
  // Capture the ad reference saved from the onAdLoaded callback.
  val ad = pipAd
  if (ad != null) {
    val options =
      PictureInPictureAdOptions.Builder()
        // Uses the Google Mobile Ads SDK's default screen position.
        .setPosition(PictureInPictureAdPosition.DEFAULT)
        // Binds the ad lifecycle to the host screen.
        .setPresentationScope(PictureInPictureAdPresentationScope.SCREEN)
        .build()
    ad.show(activity, options)
  } else {
    Log.d(TAG, "No ad to show.")
  }
}

جافا

private void showPictureInPictureAd(@NonNull Activity activity) {
  // Use the ad reference saved from the onAdLoaded callback.
  if (pipAd != null) {
    PictureInPictureAdOptions options =
        new PictureInPictureAdOptions.Builder()
            // Uses the Google Mobile Ads SDK's default screen position.
            .setPosition(PictureInPictureAdPosition.DEFAULT)
            // Binds the ad lifecycle to the host screen.
            .setPresentationScope(PictureInPictureAdPresentationScope.SCREEN)
            .build();
    pipAd.show(activity, options);
  } else {
    Log.d(TAG, "No ad to show.");
  }
}

ضبط الموضع

تعرض GMA Next-Gen SDK تلقائيًا إعلان "نافذة ضمن النافذة" في أسفل يسار الشاشة عند عرضه لأول مرة، أو في آخر موضع معروف إذا تم عرضه سابقًا. لتخصيص مكان ظهور الإعلان، يجب ضبط الموضع في خيارات "نافذة ضمن النافذة". يضبط المثال التالي الموضع أعلى المحتوى في أعلى يسار الشاشة:

Kotlin

private fun createTopLeftPositionOptions(): PictureInPictureAdOptions {
  return PictureInPictureAdOptions.Builder()
    // Sets the ad position to the top-left corner of the screen.
    .setPosition(PictureInPictureAdPosition.TOP_LEFT)
    .build()
}

جافا

private PictureInPictureAdOptions createTopLeftPositionOptions() {
  return new PictureInPictureAdOptions.Builder()
      // Sets the ad position to the top-left corner of the screen.
      .setPosition(PictureInPictureAdPosition.TOP_LEFT)
      .build();
}

للاطّلاع على جميع المواضع المتاحة، يُرجى الانتقال إلى PictureInPictureAdPosition.

ضبط نطاق العرض

تربط GMA Next-Gen SDK تلقائيًا إعلان "نافذة ضمن النافذة" بشاشة المضيف الحالية. GMA Next-Gen SDK تتجاهل الإعلان عندما لا تعود هيكلية طرق عرض شاشة المضيف في الذاكرة. لإبقاء الإعلان مرئيًا بعد إزالة شاشة المضيف من الذاكرة، يجب ضبط نطاق العرض على التطبيق:

Kotlin

private fun createApplicationScopedOptions(): PictureInPictureAdOptions {
  return PictureInPictureAdOptions.Builder()
    // Keeps the ad visible beyond the host screen's lifecycle.
    .setPresentationScope(PictureInPictureAdPresentationScope.APPLICATION)
    .build()
}

جافا

private PictureInPictureAdOptions createApplicationScopedOptions() {
  return new PictureInPictureAdOptions.Builder()
      // Keeps the ad visible beyond the host screen's lifecycle.
      .setPresentationScope(PictureInPictureAdPresentationScope.APPLICATION)
      .build();
}

لمزيد من المعلومات، يُرجى الاطّلاع على مقالة إبقاء الإعلان مرئيًا على جميع الشاشات.

ضبط معاودة الاتصال بحدث الإعلان

للتعامل مع أحداث مراحل نشاط إعلان "نافذة ضمن النافذة"، يجب ضبط معاودة الاتصال بالحدث على إعلانك قبل عرضه. تُبلغ معاودة الاتصال هذه عن الأحداث العادية، مثل النقرات ومرّات الظهور. تُبلغ معاودة الاتصال هذه أيضًا عن الأحداث الخاصة بـ "نافذة ضمن النافذة"، مثل وقت ظهور الإعلان أو إخفائه:

Kotlin

private fun setAdEventCallback(pipAd: PictureInPictureAd) {
  pipAd.adEventCallback =
    object : PictureInPictureAdEventCallback {
      override fun onAdShown() {
        Log.d(TAG, "Picture-in-Picture ad shown.")
      }

      override fun onAdHidden() {
        Log.d(TAG, "Picture-in-Picture ad hidden.")
      }

      override fun onAdImpression() {
        Log.d(TAG, "Picture-in-Picture ad recorded an impression.")
      }

      override fun onAdClicked() {
        Log.d(TAG, "Picture-in-Picture ad recorded a click.")
      }

      override fun onAdShowedFullScreenContent() {
        Log.d(TAG, "Picture-in-Picture ad showed full screen content.")
      }

      override fun onAdDismissedFullScreenContent() {
        Log.d(TAG, "Picture-in-Picture ad dismissed full screen content.")
      }

      override fun onAdFailedToShowFullScreenContent(
        fullScreenContentError: FullScreenContentError
      ) {
        Log.w(
          TAG,
          "Picture-in-Picture ad failed to show full screen content: $fullScreenContentError",
        )
      }

      override fun onAdPaid(value: AdValue) {
        Log.d(TAG, "Picture-in-Picture ad paid: ${value.valueMicros} ${value.currencyCode}")
      }
    }
}

جافا

private void setAdEventCallback(@NonNull PictureInPictureAd pipAd) {
  pipAd.setAdEventCallback(
      new PictureInPictureAdEventCallback() {
        @Override
        public void onAdShown() {
          Log.d(TAG, "Picture-in-Picture ad shown.");
        }

        @Override
        public void onAdHidden() {
          Log.d(TAG, "Picture-in-Picture ad hidden.");
        }

        @Override
        public void onAdImpression() {
          Log.d(TAG, "Picture-in-Picture ad recorded an impression.");
        }

        @Override
        public void onAdClicked() {
          Log.d(TAG, "Picture-in-Picture ad recorded a click.");
        }

        @Override
        public void onAdShowedFullScreenContent() {
          Log.d(TAG, "Picture-in-Picture ad showed full screen content.");
        }

        @Override
        public void onAdDismissedFullScreenContent() {
          Log.d(TAG, "Picture-in-Picture ad dismissed full screen content.");
        }

        @Override
        public void onAdFailedToShowFullScreenContent(
            @NonNull FullScreenContentError fullScreenContentError) {
          Log.w(
              TAG,
              "Picture-in-Picture ad failed to show full screen content: "
                  + fullScreenContentError);
        }

        @Override
        public void onAdPaid(@NonNull AdValue value) {
          Log.d(
              TAG,
              "Picture-in-Picture ad paid: "
                  + value.getValueMicros()
                  + " "
                  + value.getCurrencyCode());
        }
      });
}

إخفاء الإعلان

لإزالة الإعلان العائم من الشاشة، يجب استدعاء طريقة hide. تستدعي هذه الطريقة معاودة الاتصال بحدث إخفاء الإعلان:

Kotlin

private fun hidePictureInPictureAd() {
  // Capture the ad reference saved from the onAdLoaded callback.
  val ad = pipAd
  if (ad != null) {
    ad.hide()
  } else {
    Log.d(TAG, "No ad to hide.")
  }
}

جافا

private void hidePictureInPictureAd() {
  // Use the ad reference saved from the onAdLoaded callback.
  if (pipAd != null) {
    pipAd.hide();
  } else {
    Log.d(TAG, "No ad to hide.");
  }
}

تنظيف موارد الإعلان

لتجنُّب تسرُّب الذاكرة، يجب إسقاط مرجعك إلى عنصر الإعلان عندما ينتهي تطبيقك من استخدام الإعلان. على سبيل المثال، عندما لا يعود تطبيقك يعرض الإعلان أو يتفاعل معه مرة أخرى. بالنسبة إلى الإعلانات التي يتم عرضها على مستوى الشاشة، يجب إسقاط المرجع عندما يزيل تطبيقك شاشة المضيف من الذاكرة. بالنسبة إلى الإعلانات التي يتم عرضها على مستوى التطبيق، يجب الاحتفاظ بمرجع الإعلان أثناء انتقال المستخدم بين الشاشات، وإسقاط المرجع عندما يتجاهل المستخدم الإعلان:

Kotlin

private fun cleanUpPictureInPictureAd() {
  pipAd?.destroy()
  pipAd = null
}

جافا

private void cleanUpPictureInPictureAd() {
  // Use the ad reference saved from the onAdLoaded callback.
  if (pipAd != null) {
    pipAd.destroy();
    pipAd = null;
  }
}

إبقاء الإعلان مرئيًا على جميع الشاشات

عند ضبط نطاق العرض على التطبيق، يظلّ إعلان "نافذة ضمن النافذة" مرئيًا حتى عندما يزيل تطبيقك شاشة الاستضافة من الذاكرة. للتفاعل مع الإعلان أو تجاهله عندما ينتقل المستخدم بعيدًا عن شاشة المضيف، يجب أن يحتفظ تطبيقك بإمكانية الوصول إلى إعلان "نافذة ضمن النافذة". ننصحك بالاحتفاظ بالإعلان في عنصر أحادي على مستوى التطبيق أو في مدير حالة مشتركة بدلاً من الاحتفاظ به في متغيّر مثيل شاشة واحدة.

للاطّلاع على مثال حول كيفية إبقاء الإعلان مرئيًا على جميع الشاشات، يُرجى الاطّلاع على تطبيقاتنا النموذجية: