fc2ブログ

記事一覧

Flurry from Yahooでアプリ広告を表示する方法 | Xamarin.Forms


今回はXamarin.FormsでFlurry from Yahooの広告を表示する方法をご紹介いたします。
Flurryとは元々アクセス分析ツール(Analitics)で有名だったのですが、Yahooに買収され、広告が表示できるSDKが提供されています。
広告は日本だけでなく、海外向けに構成されています。インプレッション収益型です。


ads_02.png



前提条件
・Windows10 Pro 64Bit
・Visual Studio 2015 Community Update3
・Xamarin 4.3.0.795 (NuGet Xamarin.Forms 2.3.4.247)
・macOS Sierra 10.12.4 / Xcode8.3.1 / Xamarin.iOS 10.6.0.10



1.広告の設定

(1)新規アカウントを登録しログインします。

(2)アプリを登録します。
メニューの Admin > Manage > Apps から必要なアプリ(iOS/Android毎)を登録します。

(3)広告を登録します。
メニューの Monetization > Apps & Ad Units から +Ad Unit ボタンを押下し、広告設定を登録します。

flurry_01.png


Ad Unit Name : 任意ですが、ソースコードに組み込みます。アプリ毎広告毎に一意の名称にした方が良いでしょう。
App : (1)で登録したAppを選択してください。
Type : 導入当初はデフォルトのStandardのままで大丈夫です。
Placement : 広告の表示形態を選択します。バナー広告の場合はBannerを選択しましょう。Full Screenはインタースティシャル(interstitial)つまり全面広告のことです。
Display Minimum (CPM Floor) : 導入当初はデフォルトの0の方が広告が表示されやすいのでは?
Video Minimum (CPM Floor) : 導入当初はデフォルトの0の方が広告が表示されやすいのでは?



2.SDKのインストール

(1)NuGetパッケージマネージャを開き、Flurryで検索します。

xamarin_flurry_02.png


(2)Flurry.Adsを選択し、必要なプロジェクトにインストールします。
   Flurry.Analytictsも同時にインストールされます。

以上でSDKのインストールは完了です。

また、以下のサイトからサンプルコードがDownloadできます。
https://components.xamarin.com/view/flurry.ads
※SDKではありません。



3.iOSの実装方法

(1)FlurryのSDKを初期化します。
API Key はFlurryのサイトの Monetization > Apps & Ad Units から取得できます。

AppDelegate.cs
using Flurry.Ads;
using Flurry.Analytics;
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();

        //Flurry
#if DEBUG
        // enable test ads
        FlurryAds.EnableTestAds(true);
#endif
        FlurryAgent.StartSession("API_Key");
        FlurryAgent.SetDebugLogEnabled(true);
        FlurryAgent.SetLogLevel(FlurryLogLevel.All);

        LoadApplication(new App());
        return base.FinishedLaunching(app, options);
    }
}


(2)バナーの場合
レンダラーを使用して表示できるようにしてあります。
AdBannerクラスはXamarin.Forms.Viewクラスを継承したクラスです。
AdBannerクラスをPCLで配置して使用します。
AdUnitNameは Flurryのサイトで Monetization > Apps & Ad Units から取得できます。

AdBannerRenderer.cs
using Flurry.Ads;
using Flurry.Ads.Banner;
[assembly: ExportRenderer(typeof(AdBanner), typeof(AppName.iOS.AdBannerRenderer))]
namespace AppName.iOS
{
    public class AdBannerRenderer : ViewRenderer
    {
        UIViewController viewCtrl = null;
        BannerView adView;
        bool viewOnScreen = false;

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
            {
                //Flurry Banner
                this.ShowFlurryBanner(UIApplication.SharedApplication.KeyWindow.RootViewController,
                                      "AdUnitName");
            }

        }

        private void ShowFlurryBanner(UIViewController viewController,
                                      string adUnitName)
        {
            FlurryAdBanner adBanner = new FlurryAdBanner(adUnitName);

#if DEBUG
            // enable test ads
            var targeting = FlurryAdTargeting.Targeting;
            targeting.TestAdsEnabled = true;
            adBanner.Targeting = targeting;
#endif

            adBanner.DidFetchAd += delegate {
                Console.WriteLine(String.Format(" [{0}] Did Fetch Ad ", adBanner.Space));

                adBanner.DisplayAd(viewController.View, viewController);
            };
            adBanner.DidRenderAd += delegate {
                Console.WriteLine(String.Format(" [{0}] Did Render Ad ", adBanner.Space));
            };
            adBanner.WillPresentFullscreen += delegate {
                Console.WriteLine(String.Format(" [{0}] Will Present Fullscreen Ad ", adBanner.Space));
            };
            adBanner.DidReceiveClick += delegate {
                Console.WriteLine(String.Format(" [{0}] Did Receive Click Ad ", adBanner.Space));
            };
            adBanner.DidDismissFullscreen += delegate {
                Console.WriteLine(String.Format(" [{0}] Did Dismiss Fullscreen Ad ", adBanner.Space));
            };
            adBanner.WillLeaveApplication += delegate {
                Console.WriteLine(String.Format(" [{0}] Will Leave Application ", adBanner.Space));
            };
            adBanner.DidFinishVideo += delegate {
                Console.WriteLine(String.Format(" [{0}] Did Finish Video ", adBanner.Space));
            };
            adBanner.WillPresentFullscreen += delegate {
                Console.WriteLine(String.Format(" [{0}] Will Present Fullscreen Ad ", adBanner.Space));
            };
            adBanner.Error += (_, e) => {
                Console.WriteLine(String.Format(" [{0}] Did Fail to Receive Ad with error [{1}] ", adBanner.Space, e.ErrorDescription));
            };

            Console.WriteLine(String.Format(" [{0}] Will Fetch Ad ", adBanner.Space));

            adBanner.FetchAd(viewController.View.Frame);
        }
    }
}


(3)Interstitialの場合
DependencyService等でコールすると良いでしょう。

using Flurry.Ads.Interstitial;
/// <summary>
/// Flurry Interstitial
/// </summary>
/// <param name="adUnitName"></param>
private void ShowFlurryInterstitial(string adUnitName)
{
    FlurryAdInterstitial adInterstitial = new FlurryAdInterstitial(adUnitName);

#if DEBUG
    // enable test ads
    var targeting = FlurryAdTargeting.Targeting;
    targeting.TestAdsEnabled = true;
    adInterstitial.Targeting = targeting;
#endif

    adInterstitial.DidFetchAd += delegate {
        Console.WriteLine(String.Format(" [{0}] Did Fetch Ad ", adInterstitial.Space));
        adInterstitial.Present(UIApplication.SharedApplication.KeyWindow.RootViewController);
    };
    adInterstitial.DidRenderAd += delegate {
        Console.WriteLine(String.Format(" [{0}] Did Render Ad ", adInterstitial.Space));
    };
    adInterstitial.DidDismissAd += delegate {
        Console.WriteLine(String.Format(" [{0}] Will Present Fullscreen Ad ", adInterstitial.Space));
    };
    adInterstitial.DidReceiveClick += delegate {
        Console.WriteLine(String.Format(" [{0}] Did Receive Click Ad ", adInterstitial.Space));
    };
    adInterstitial.DidDismissAd += delegate {
        Console.WriteLine(String.Format(" [{0}] Did Dismiss Fullscreen Ad ", adInterstitial.Space));
    };
    adInterstitial.WillLeaveApplication += delegate {
        Console.WriteLine(String.Format(" [{0}] Will Leave Application ", adInterstitial.Space));
    };
    adInterstitial.DidFinishVideo += delegate {
        Console.WriteLine(String.Format(" [{0}] Did Finish Video ", adInterstitial.Space));
    };
    adInterstitial.WillPresentAd += delegate {
        Console.WriteLine(String.Format(" [{0}] Will Present Fullscreen Ad ", adInterstitial.Space));
    };
    adInterstitial.Error += (_, ex) => {
        Console.WriteLine(String.Format(" [{0}] Did Fail to Receive Ad with error [{1}] ", adInterstitial.Space, ex.ErrorDescription));
    };

    Console.WriteLine(String.Format(" [{0}] Will Fetch Ad ", adInterstitial.Space));

    adInterstitial.FetchAd();

}



4.iOSの表示結果


ContactFriends
xamarin_flurry_03.png
ExplorerDx
xamarin_flurry_04.png
Interstitial
xamarin_flurry_06.png


個人的な感想ですが、日本に特化しておらず、海外のユーザーがターゲットなので、バナー広告には洗練された広告が少ない印象を受けました。



5.Androidの実装方法

(1)FlurryのSDKを初期化します。
API Key はFlurryのサイトの Monetization > Apps & Ad Units から取得できます。

MainActivity.cs
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        global::Xamarin.Forms.Forms.Init(this, bundle);

        //Flurry
        FlurryAgent.SetLogEnabled(true);
        FlurryAgent.SetLogEvents(true);
        FlurryAgent.SetLogLevel(LogPriority.Verbose);
        FlurryAgent.Init(this, "API_Key");

        LoadApplication(new App(path));
    }
}


(2)バナーの場合
レンダラーを使用して表示できるようにしてあります。
AdBannerクラスはXamarin.Forms.Viewクラスを継承したクラスです。
AdBannerクラスをPCLで配置して使用します。
AdUnitNameは Flurryのサイトで Monetization > Apps & Ad Units から取得できます。

AdBannerRenderer.cs
using Flurry.Ads;
[assembly: ExportRenderer(typeof(AdBanner), typeof(AdBannerRenderer))]
namespace AppName.Android
{
    public class AdBannerRenderer : ViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
            {
                var adsbanner = (AdBanner)Element;
                //Flurry Banner
                this.ShowFlurryBanner("AdUnitName");
            }
        }

        private void ShowFlurryBanner(string adUnitName)
        {
            //Flurry Yahoo
            global::Android.Widget.RelativeLayout bannerContainer = new global::Android.Widget.RelativeLayout(Xamarin.Forms.Forms.Context);
            base.SetNativeControl(bannerContainer);

            // create the ad instance
            var adBanner = new FlurryAdBanner(Xamarin.Forms.Forms.Context,
                                              bannerContainer,
                                              adUnitName);

            adBanner.Fetched += delegate
            {
                // display the ad
                adBanner.DisplayAd();
            };
            adBanner.Rendered += delegate
            {
                Console.WriteLine("Banner.Rendered");
            };
            adBanner.ShowFullscreen += delegate
            {
                Console.WriteLine("Banner.ShowFullscreen");
            };
            adBanner.Clicked += delegate
            {
                Console.WriteLine("Banner.Clicked");
            };
            adBanner.CloseFullscreen += delegate
            {
                Console.WriteLine("Banner.CloseFullscreen");
            };
            adBanner.AppExit += delegate
            {
                Console.WriteLine("Banner.AppExit");
            };
            adBanner.VideoCompleted += delegate
            {
                Console.WriteLine("Banner.VideoCompleted");
            };
            adBanner.Error += (_, ex) =>
            {
                Console.WriteLine("Banner.Error [{0}] [{1}] ", ex.ErrorType, ex.ErrorCode);
                //Error code      Error summary                   Error description
                //1               No network connectivity There is no internet connection
                //2               Missing ad controller Could happen when ad has not been prepared yet
                //3               No context                      A valid context is missing
                //4               Invalid ad unit
                //17              Ad not ready Triggered when you call displayAd() on an ad object that is not ready
                //18              Wrong orientation               Device is in wrong orientation for banner or interstitial ads
                //19              No view group                   Banner ad wasn't placed in a ViewGroup
                //20              Ad was unfilled                 Ad was unfilled by server.Could be due to incorrect ad request, incorrect ad space

                //                             configuration or no fill at request location at the moment
                //21              Incorrect class for ad space    Ad request made with incorrect class for corresponding ad space
                //22              Device locked                   Device is locked during ad request
            };

            // fetch the ad
            adBanner.FetchAd();

        }
    }   
}


(3)Interstitialの場合
DependencyService等でコールすると良いでしょう。

using Flurry.Ads;
private FlurryAdInterstitial _adInterstitial;
private void ShowFlurryInterstitial(string adUnitName)
{
    if (_adInterstitial != null)
    {
        _adInterstitial.Destroy();
    }

    _adInterstitial = new FlurryAdInterstitial(Xamarin.Forms.Forms.Context,
                                               adUnitName);

    _adInterstitial.Fetched += delegate
    {
        Console.WriteLine("Interstitial.Fetched");

        _adInterstitial.DisplayAd();
    };
    _adInterstitial.Rendered += delegate
    {
        Console.WriteLine("Interstitial.Rendered");
    };
    _adInterstitial.Display += delegate
    {
        Console.WriteLine("Interstitial.Display");
    };
    _adInterstitial.Clicked += delegate
    {
        Console.WriteLine("Interstitial.Clicked");
    };
    _adInterstitial.Close += delegate
    {
        Console.WriteLine("Interstitial.Close");
    };
    _adInterstitial.AppExit += delegate
    {
        Console.WriteLine("Interstitial.AppExit");
    };
    _adInterstitial.VideoCompleted += delegate
    {
        Console.WriteLine("Interstitial.VideoCompleted");
    };
    _adInterstitial.Error += (_, e) =>
    {
        Console.WriteLine(string.Format("Interstitial.Error [{0}] [{1}] ", e.ErrorType, e.ErrorCode));
    };

    Console.WriteLine("Interstitial.FetchAd");

    _adInterstitial.FetchAd();
}



6.Androidの表示結果


Android4
xamarin_flurry_05.png



7.注意点

・広告を登録・変更して表示される(反映)までに1~2時間程かかります。
・AndroidでError Code:20が返される場合は、広告切れの様です。
・iOSで Code 104: "FlurryAds: No ads available from server for this space."が返される場合は、その地域/時間での表示可能な広告が無いことを示しています。
・シミュレータでは広告が表示されません。





最後までお読みいただきありがとうございます。
当ブログの内容をまとめた Xamarin逆引きメニュー は以下のURLからご覧になれます。
https://itblog.dynaspo.com/blog-entry-81.html


関連記事

コメント

コメントの投稿

※名前とタイトルが入力されていないコメントでは他のコメントとの区別ができません。

 入力されていないコメントには返信しませんのであらかじめご了承くださいませ。

※ニックネームでも良いので必ずご入力ください。

    

※必ずご入力ください。

    
    

※必ずご入力ください。

※技術的な質問には環境やエラーについて正確かつ詳細にお教えください。

・正確なエラーの内容

・Windowsのバージョン番号

・Visual Studioのバージョン

・機器の型番

・アプリやソフトのバージョン

    

カテゴリ別記事一覧

広告

プロフィール

石河 純


著者名 :石河 純
自己紹介:素人上がりのIT技術者。趣味は卓球・車・ボウリング

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Catalina 10.15 / Mojave 10.14 / High Sierra 10.13 / Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
【データベース】
Oracle 10g/9i
SQLServer 2016/2008R2/2005/2000
SQLAnywhere 16/11/8
【BI/レポートツール】
Cognos ReportNet (IBM)
Microsoft PowerBI
ActiveReport (GrapeCity)
CrystalReport
【OCX関連】
GrapeCity InputMan SPREAD MultiRow GridView
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS jQuery IIS6/7 apache2

休みの日は卓球をやっています。
現在、卓球用品通販ショップは休業中です。