記事一覧

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からご覧になれます。
http://itblogdsi.blog.fc2.com/blog-entry-81.html


関連記事

コメント

コメントの投稿

カテゴリ別記事一覧

広告

プロフィール

石河 純


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

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語・データベース】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
Oracle10g SQLServer2008R2 SQLAnywhere8/11/16
ActiveReport CrystalReport ReportNet(IBM)
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS IIS6/7 apache2

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