الإعلانات على شاشة فتح التطبيق

اختيار النظام الأساسي: Android iOS Unity Flutter Android (قديم)

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

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

المتطلبات الأساسية

قبل المتابعة، عليك تنفيذ ما يلي:

  • ثبِّت المكوّن الإضافي Flutter بالإصدار 0.13.6 أو إصدار أحدث.
  • إعداد Google Mobile Ads Flutter Plugin يجب أن يتضمّن تطبيق Flutter استيراد Google Mobile Ads Flutter Plugin.

اختبِر دائمًا باستخدام الإعلانات الاختبارية

عند إنشاء تطبيقاتك واختبارها، تأكَّد من استخدام الإعلانات الاختبارية بدلاً من الإعلانات المباشرة والإنتاجية. وقد يؤدي عدم إجراء ذلك إلى تعليق حسابك.

أسهل طريقة لتحميل الإعلانات الاختبارية هي استخدام معرّفات الوحدات الإعلانية الاختبارية المخصّصة لـ "الإعلانات مقابل مكافأة" على Android وiOS:

Android

ca-app-pub-3940256099942544/9257395921

iOS

ca-app-pub-3940256099942544/5575463023

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

التنفيذ

في ما يلي الخطوات الرئيسية لدمج "الإعلانات على شاشة فتح التطبيق":

  1. أنشئ فئة خدماتية تحمّل إعلانًا قبل أن تحتاج إلى عرضه.
  2. حمِّل إعلانًا.
  3. سجِّل لعمليات ردّ الاتصال واعرِض الإعلان.
  4. اشترِك في AppStateEventNotifier.appStateStream لعرض الإعلان أثناء أحداث فتح التطبيق.

إنشاء فئة خدمات

أنشِئ فئة جديدة باسم AppOpenAdManager لتحميل الإعلان. تدير هذه الفئة متغيّر مثيل لتتبُّع إعلان تم تحميله ومعرّف الوحدة الإعلانية لكل منصة.

import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'dart:io' show Platform;

class AppOpenAdManager {
  
  String adUnitId = Platform.isAndroid
    ? 'ca-app-pub-3940256099942544/9257395921'
    : 'ca-app-pub-3940256099942544/5575463023';
  
  AppOpenAd? _appOpenAd;
  bool _isShowingAd = false;

  /// Load an AppOpenAd.
  void loadAd() {
    // We will implement this below.
  }

  /// Whether an ad is available to be shown.
  bool get isAdAvailable {
    return _appOpenAd != null;
  }
}

تحميل إعلان

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

يتم تحميل الإعلان باستخدام طريقة load في فئة AppOpenAd. تتطلّب طريقة التحميل معرّف وحدة إعلانية ووضع اتجاه وعنصر AdRequest ومعالج إكمال يتم استدعاؤه عند نجاح تحميل الإعلان أو تعذّره. يتم تقديم عنصر AppOpenAd الذي تم تحميله كمَعلمة في معالج الإكمال. يوضّح المثال التالي كيفية تحميل AppOpenAd.

public class AppOpenAdManager {
  ...

  /// Load an AppOpenAd.
  void loadAd() {
    AppOpenAd.load(
      adUnitId: adUnitId,
      adRequest: AdRequest(),
      adLoadCallback: AppOpenAdLoadCallback(
        onAdLoaded: (ad) {
          _appOpenAd = ad;
        },
        onAdFailedToLoad: (error) {
          print('AppOpenAd failed to load: $error');
          // Handle the error.
        },
      ),
    );
  }
}

عرض الإعلان ومعالجة عمليات الاستدعاء بملء الشاشة

قبل عرض الإعلان، سجِّل FullScreenContentCallback لكل حدث إعلان تريد الاستماع إليه.

public class AppOpenAdManager {
  ...

  public void showAdIfAvailable() {
    if (!isAdAvailable) {
      print('Tried to show ad before available.');
      loadAd();
      return;
    }
    if (_isShowingAd) {
      print('Tried to show ad while already showing an ad.');
      return;
    }
    // Set the fullScreenContentCallback and show the ad.
    _appOpenAd!.fullScreenContentCallback = FullScreenContentCallback(
      onAdShowedFullScreenContent: (ad) {
        _isShowingAd = true;
        print('$ad onAdShowedFullScreenContent');
      },
      onAdFailedToShowFullScreenContent: (ad, error) {
        print('$ad onAdFailedToShowFullScreenContent: $error');
        _isShowingAd = false;
        ad.dispose();
        _appOpenAd = null;
      },
      onAdDismissedFullScreenContent: (ad) {
        print('$ad onAdDismissedFullScreenContent');
        _isShowingAd = false;
        ad.dispose();
        _appOpenAd = null;
        loadAd();
      },
    );
  }
}

إذا عاد المستخدم إلى تطبيقك بعد مغادرته من خلال النقر على "إعلان على شاشة فتح التطبيق"، تأكَّد من عدم عرض "إعلان على شاشة فتح التطبيق" آخر له.

الاستماع إلى أحداث فتح التطبيق

لتلقّي إشعارات بشأن أحداث فتح التطبيق، عليك الاشتراك في AppStateEventNotifier.appStateStream والاستماع إلى أحداث foreground.

import 'package:app_open_example/app_open_ad_manager.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

/// Listens for app foreground events and shows app open ads.
class AppLifecycleReactor {
  final AppOpenAdManager appOpenAdManager;

  AppLifecycleReactor({required this.appOpenAdManager});

  void listenToAppStateChanges() {
    AppStateEventNotifier.startListening();
    AppStateEventNotifier.appStateStream
        .forEach((state) => _onAppStateChanged(state));
  }

  void _onAppStateChanged(AppState appState) {
    // Try to show an app open ad if the app is being resumed and
    // we're not already showing an app open ad.
    if (appState == AppState.foreground) {
      appOpenAdManager.showAdIfAvailable();
    }
  }
}

يمكنك الآن إعداد AppLifecycleReactor وبدء تتبّع تغييرات مراحل نشاط التطبيق. على سبيل المثال، من صفحتك الرئيسية:

import 'package:app_open_example/app_open_ad_manager.dart';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

import 'app_lifecycle_reactor.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'App Open Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'App Open Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

/// Example home page for an app open ad.
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  late AppLifecycleReactor _appLifecycleReactor;

  @override
  void initState() {
    super.initState();
    
    AppOpenAdManager appOpenAdManager = AppOpenAdManager()..loadAd();
    _appLifecycleReactor = AppLifecycleReactor(
      appOpenAdManager: appOpenAdManager);
  }

مراعاة انتهاء صلاحية الإعلانات

لضمان عدم عرض إعلان منتهي الصلاحية، أضِف طابعًا زمنيًا إلى AppOpenAdManager حتى تتمكّن من التحقّق من المدة التي انقضت منذ تحميل إعلانك. بعد ذلك، استخدِم هذا الطابع الزمني للتحقّق مما إذا كان الإعلان لا يزال صالحًا.

/// Utility class that manages loading and showing app open ads.
class AppOpenAdManager {
  ...
  
  /// Maximum duration allowed between loading and showing the ad.
  final Duration maxCacheDuration = Duration(hours: 4);

  /// Keep track of load time so we don't show an expired ad.
  DateTime? _appOpenLoadTime;
  
  ...

  /// Load an AppOpenAd.
  void loadAd() {
    AppOpenAd.load(
      adUnitId: adUnitId,
      orientation: AppOpenAd.orientationPortrait,
      adRequest: AdRequest(),
      adLoadCallback: AppOpenAdLoadCallback(
        onAdLoaded: (ad) {
          print('$ad loaded');
          _appOpenLoadTime = DateTime.now();
          _appOpenAd = ad;
        },
        onAdFailedToLoad: (error) {
          print('AppOpenAd failed to load: $error');
        },
      ),
    );
  }

  /// Shows the ad, if one exists and is not already being shown.
  ///
  /// If the previously cached ad has expired, this just loads and caches a
  /// new ad.
  void showAdIfAvailable() {
    if (!isAdAvailable) {
      print('Tried to show ad before available.');
      loadAd();
      return;
    }
    if (_isShowingAd) {
      print('Tried to show ad while already showing an ad.');
      return;
    }
    if (DateTime.now().subtract(maxCacheDuration).isAfter(_appOpenLoadTime!)) {
      print('Maximum cache duration exceeded. Loading another ad.');
      _appOpenAd!.dispose();
      _appOpenAd = null;
      loadAd();
      return;
    }
    // Set the fullScreenContentCallback and show the ad.
    _appOpenAd!.fullScreenContentCallback = FullScreenContentCallback(...);
    _appOpenAd!.show();
  }
}

التشغيل على البارد وشاشات التحميل

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

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

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

أفضل الممارسات

تساعدك "الإعلانات على شاشة فتح التطبيق" في تحقيق الربح من شاشة تحميل تطبيقك، عند تشغيل التطبيق لأول مرة وأثناء التبديل بين التطبيقات، ولكن من المهم مراعاة أفضل الممارسات حتى يستمتع المستخدمون باستخدام تطبيقك. من الأفضل:

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

مثال كامل على GitHub

للاطّلاع على المثال الكامل، يُرجى مراجعة العرض التوضيحي لواجهة برمجة التطبيقات.