拡張機能をプロジェクトに接続する
この記事のフレームワークでは、Marmalade SDK環境で開発されたモバイルアプリケーション向けに、いくつかの広告サービスのインタースティシャルバナーを接続する方法を説明します。
したがって、これらのサービスの接続に関するマーマレードのドキュメントを既にお読みになっていること、および以下のサイトにアカウントを持ち、アプリケーションを登録していることを確信しています。
アプリケーションを登録するとき、システムはそれに識別子(またはChartboostで行われるように識別子のペア)を割り当てます。これにより、広告サービスとやり取りするときにアプリケーションが識別されます。
現在、Marmalade SDKバージョン7.8.0p3 [439542]を使用しています。 アセンブリには、私たちにとって興味のある次の拡張が既に含まれています。
- %SDKインストールフォルダー%/拡張機能/ s3eGoogleAdMob
- %SDKインストールフォルダー%/拡張機能/ s3eInMobiAds
- %SDKインストールフォルダー%/ extensions / s3eChartboost
Leadboltの拡張機能は、標準配布には含まれていません。 マーマレードのドキュメントでは、
help.leadbolt.comからダウンロードすることを推奨しています。 AdMob、Inmobi、Chartboostとは異なり、LeadboltはAndroidとiOSに個別の拡張機能を提供します。 これらの拡張機能は、最も便利な方法で記述されていません。つまり、それらの一部の機能は同じと呼ばれ、2つの拡張機能を1つのプロジェクトに一度に接続しようとすると衝突が発生します。 したがって、衝突を避けるために必要なすべてのメソッドに接尾辞iOSを追加して、iOSの拡張機能を少し変更しました。 私が使用する拡張機能は、github
github.com/akk0rd87/Marmalade-Leabolt-SDKで入手できます。 それらをダウンロードして/ extensions /にコピーして取得します
%SDKインストールフォルダー%/拡張機能/ AppTrackerAndroid
%SDKインストールフォルダー%/拡張機能/ AppTrackerIOS
mkbファイルの
サブプロジェクトセクションに拡張機能を
含めます。
Subprojects { ... s3eInMobiAds s3eGoogleAdMob s3eChartBoost AppTrackerAndroid AppTrackeriOS }
展開セクションで、AppTracker.jarリンク(デフォルトではAppTrackerAndroidにあり、common / jarフォルダーに配置)とAnrdoidアプリケーションのChartboost識別子を追加します。
deployment { ... # THIS NEED FOR LEADBOLT ON ANDROID android-external-jars='../common/jar/AppTracker.jar' android-extra-strings='(gps_app_id,0), (chartboost_appid, *********),(chartboost_appsig, ***************)' }
広告サービスとのアプリケーションの相互作用
アプリケーションと広告サービス間の相互作用の一般原則:
- アプリケーションの初期化時に、広告サービスとの対話セッションが初期化されます。
- 開発者が決定した時点で、バナーをキャッシュする要求が行われます
- バナーをキャッシュするためのリクエストの後、対応するコールバックハンドラー関数が呼び出されます。そのパラメーターは、キャッシュリクエストが完了したか、エラーが発生したかを示します。
- 開発者が決定した時点で、最後のキャッシュリクエストの結果がチェックされ、成功した場合は、広告を表示するメソッドが呼び出されます。
- ユーザーのアクション(たとえば、クリック、動画の完全表示、動画広告の終了など)に応じて、対応するコールバックハンドラー関数も呼び出すことができます。
- アプリケーションを閉じるとき、セッションを閉じます。
adengine_constants.hで説明されている次のセッション状態は、上記の原則に従っています。
#define AD_ENGINE_TEMPORARY 0
各拡張子のCPPファイル
特定の広告サービスとのやり取りのロジックが記述されているファイルが含まれています。 Leadboltの場合、2つのファイルを接続します。これらのOSには個別の拡張機能があるため、iOSとAndroidに別々に接続します。 このロジックを制御するadengine.cppファイルも含まれています。 また、対応するAPI関数が記述される対応する.h-headerを作成することを忘れないでください。 実際、adengine.cppは私の広告エンジンであり、いくつかのアプリケーションで使用しています。 アプリケーション識別子をハードコーディングしないように、この目的のために、各プロジェクトにlocal.cppファイルを追加します。このファイルには、個々のアプリケーションごとに独自の実装があります。
mkbファイルの
ファイルセクション:
{ ... adengine.cpp googleadmob.cpp inmobi.cpp leadbolt_ios.cpp leadbolt_android.cpp charboost.cpp local.cpp }
googleadmob.cpp #include "s3eGoogleAdMob.h" #include "adengine_constants.h" int googlead_mob_status = AD_ENGINE_NOT_INITED; s3eGoogleAdMobId m_Id = 0; void DestroyAdMobAd() { s3eResult res = s3eGoogleAdMobDestroyAd(m_Id); } static int32 onAdMobLoad(void* systemData, void* userData) { googlead_mob_status = AD_ENGINE_LOAD_OK; return 0; } static int32 onAdMobAction(void* systemData, void* userData) { DestroyAdMobAd(); googlead_mob_status = AD_ENGINE_INITED; return 0; } static int32 onAdMobError(void* systemData, void* userData) { DestroyAdMobAd(); googlead_mob_status = AD_ENGINE_LOAD_ERR; return 0; } static int32 onAdMobFiledToLoad(void* systemData, void* userData) { DestroyAdMobAd(); googlead_mob_status = AD_ENGINE_LOAD_ERR; return 0; }
inmobi.cpp #include "s3eInMobiAds.h" #include "s3e.h" #include "adengine_constants.h" int InMobi_ad_state = AD_ENGINE_NOT_INITED; static int int_request_completed(void *systemData, void *userData) { InMobi_ad_state = AD_ENGINE_LOAD_OK; return S3E_RESULT_SUCCESS; } static int int_request_failed(void *systemData, void *userData) { InMobi_ad_state = AD_ENGINE_LOAD_ERR; return S3E_RESULT_SUCCESS; } static int int_show_adscreen(void *systemData, void *userData) { return S3E_RESULT_SUCCESS; } static int int_dismiss_adscreen(void *systemData, void *userData) { InMobi_ad_state = AD_ENGINE_INITED; return S3E_RESULT_SUCCESS; } static int int_leave_application(void *systemData, void *userData) { InMobi_ad_state = AD_ENGINE_INITED; return S3E_RESULT_SUCCESS; } static int int_ad_interacted(void *systemData, void *userData) { InMobi_ad_state = AD_ENGINE_INITED; return S3E_RESULT_SUCCESS; } static int DeviceStateChangeCallback(void *systemData, void *userData) { InMobi_ad_state = AD_ENGINE_INITED; return S3E_RESULT_SUCCESS; } void InMobi_Init(char appcode[50]) { InMobiAdsRegisterIntCallback(INMOBIADS_CALLBACK_INT_REQUEST_COMPLETED, int_request_completed, NULL); InMobiAdsRegisterIntCallback(INMOBIADS_CALLBACK_INT_REQUEST_FAILED, int_request_failed, NULL); InMobiAdsRegisterIntCallback(INMOBIADS_CALLBACK_INT_SHOW_ADSCREEN, int_show_adscreen, NULL); InMobiAdsRegisterIntCallback(INMOBIADS_CALLBACK_INT_DISMISS_ADSCREEN, int_dismiss_adscreen, NULL); InMobiAdsRegisterIntCallback(INMOBIADS_CALLBACK_INT_LEAVE_APPLICATION, int_leave_application, NULL); InMobiAdsRegisterIntCallback(INMOBIADS_CALLBACK_INT_INTERACTED, int_ad_interacted, NULL); s3eDeviceRegister(S3E_DEVICE_UNPAUSE, DeviceStateChangeCallback, NULL); inmobi_initialize(appcode); inmobi_interstitial_init(appcode); InMobi_ad_state = AD_ENGINE_INITED; } void InMobi_Load() { InMobi_ad_state = AD_ENGINE_TEMPORARY; inmobi_interstitial_load(""); } void InMobi_Show() { InMobi_ad_state = AD_ENGINE_TEMPORARY; inmobi_interstitial_show(); } void InMobi_Release() { InMobi_ad_state = AD_ENGINE_TERMINATED; inmobi_interstitial_release(); InMobiAdsUnRegisterIntCallback(INMOBIADS_CALLBACK_INT_REQUEST_COMPLETED, int_request_completed); InMobiAdsUnRegisterIntCallback(INMOBIADS_CALLBACK_INT_REQUEST_FAILED, int_request_failed); InMobiAdsUnRegisterIntCallback(INMOBIADS_CALLBACK_INT_SHOW_ADSCREEN, int_show_adscreen); InMobiAdsUnRegisterIntCallback(INMOBIADS_CALLBACK_INT_DISMISS_ADSCREEN, int_dismiss_adscreen); InMobiAdsUnRegisterIntCallback(INMOBIADS_CALLBACK_INT_LEAVE_APPLICATION, int_leave_application); InMobiAdsUnRegisterIntCallback(INMOBIADS_CALLBACK_INT_INTERACTED, int_ad_interacted); s3eDeviceUnRegister(S3E_DEVICE_UNPAUSE, DeviceStateChangeCallback); } int InMobi_Status() { return InMobi_ad_state; } s3eBool InMobi_Avaliable() { return s3eInMobiAdsAvailable(); }
leadbolt_ios.cpp #include "AppTrackeriOS.h" #include "adengine_constants.h" int ldb_ios_ad_state = AD_ENGINE_NOT_INITED; void LBD_IOS_DoDestroy() { AppTrackeriOS_destroyModule(); } int32 LBD_IOS_onModuleFailedEvent(void* system, void* user){ ldb_ios_ad_state = AD_ENGINE_LOAD_ERR; return 0; } int32 LBD_IOS_onModuleClosedEvent(void* system, void* user){ LBD_IOS_DoDestroy(); ldb_ios_ad_state = AD_ENGINE_INITED; return 0; } int32 LBD_IOS_onModuleClickedEvent(void* system, void* user){ return 0; } int32 LBD_IOS_onModuleLoadedEvent(void* system, void* user){ ldb_ios_ad_state = AD_ENGINE_SHOW_OK; return 0; } int32 LBD_IOS_onModuleCacheEvent(void* system, void* user){ ldb_ios_ad_state = AD_ENGINE_LOAD_OK; return 0; } int32 LBD_IOS_onMediaFinishedEvent(void* system, void* user){ LBD_IOS_DoDestroy(); ldb_ios_ad_state = AD_ENGINE_INITED; return 0; }
leadbolt_android.cpp #include "AppTrackerAndroid.h" #include "adengine_constants.h" int ldb_ad_state = AD_ENGINE_NOT_INITED; void DoDestroy() { destroyModule(); } int32 onModuleFailedEvent(void* system, void* user){ ldb_ad_state = AD_ENGINE_LOAD_ERR; return 0; } int32 onModuleClosedEvent(void* system, void* user){ DoDestroy(); ldb_ad_state = AD_ENGINE_INITED; return 0; } int32 onModuleClickedEvent(void* system, void* user){ return 0; } int32 onModuleLoadedEvent(void* system, void* user){ ldb_ad_state = AD_ENGINE_SHOW_OK; return 0; } int32 onModuleCacheEvent(void* system, void* user){ ldb_ad_state = AD_ENGINE_LOAD_OK; return 0; } int32 onMediaFinishedEvent(void* system, void* user){ DoDestroy(); ldb_ad_state = AD_ENGINE_INITED; return 0; }
charboost.cpp #include "s3e.h" #include "s3eChartBoost.h" #include "adengine_constants.h" int charboost_ad_state = AD_ENGINE_NOT_INITED; void RequestCB(void* systemData, void* userData) { charboost_ad_state = AD_ENGINE_LOAD_OK; } void AdvertisementClosed(void* System, void* User) { charboost_ad_state = AD_ENGINE_INITED; } void AdvertisementDismissed(void* System, void* User) { charboost_ad_state = AD_ENGINE_INITED; } void AdvertisementClicked(void* System, void* User) { charboost_ad_state = AD_ENGINE_INITED; } void ErrorCallback(void* System, void* User) { charboost_ad_state = AD_ENGINE_LOAD_ERR; }
local.cpp-マスクされたアプリケーション識別子 #include <string.h> #include "s3e.h" void GetInMobiAppAdIdentifier(char code[]) { int os = s3eDeviceGetInt(S3E_DEVICE_OS); switch (os) { case S3E_OS_ID_ANDROID: strcpy(code, "********************************"); break; case S3E_OS_ID_IPHONE: strcpy(code, "********************************"); break; // case S3E_OS_ID_WINDOWS: // break; } } void GetLDBAppAdIdentifier(char code[]) { int os = s3eDeviceGetInt(S3E_DEVICE_OS); switch (os) { case S3E_OS_ID_ANDROID: strcpy(code, "********************************"); break; case S3E_OS_ID_IPHONE: strcpy(code, "********************************"); break; // case S3E_OS_ID_WINDOWS: // break; } } void GetCharBoostIdentifiers (char app[], char signature[]) { int os = s3eDeviceGetInt(S3E_DEVICE_OS); switch (os) { case S3E_OS_ID_ANDROID: strcpy(app , "************************"); strcpy(signature, "****************************************"); break; case S3E_OS_ID_IPHONE: strcpy(app , "************************"); strcpy(signature, "****************************************"); break; // case S3E_OS_ID_WINDOWS: // break; } } void GetAdMobAdIdentifier(char code[]) { int os = s3eDeviceGetInt(S3E_DEVICE_OS); switch (os) { case S3E_OS_ID_ANDROID: strcpy(code, "ca-app-pub-***************************"); break; case S3E_OS_ID_IPHONE: strcpy(code, "ca-app-pub-***************************"); break; // case S3E_OS_ID_WINDOWS: // break; } }
AdEngine-アプリケーションのAPI
テストにより、ChartBoost-APIが実際にコールバックを呼び出さないことが明らかになりました(そして、
answers.madewithmarmalade.comで確認されました)-これはバグです。 これに関連して:
- バナーキャッシュリクエストが正常に完了したかどうかを確認する機会はありません。
- ChartBoostを優先します。
広告エンジンのロジックは次のとおりです。
-少なくとも1つのサービスがバナーをキャッシュするまで、バナーのキャッシュを要求することにより、広告を表示する予想される瞬間の少し前。
-広告を表示する必要があるとき、何かがキャッシュされたサービスから、最も高い優先度を選択し、そのバナーを表示します。
-どのサービスにも何もキャッシュされていない場合、ChartBoostバナー表示メソッドを呼び出します。 この場合、広告は表示されますか?幸運です。
adengine.cpp #include "local.h" #include "s3e.h" #include "inmobi.h" #include "leadbolt_ios.h" #include "leadbolt_android.h" #include "googleadmob.h" #include "charboost.h" #define DELAY_MS 1000
AndroidManifest.xmlを編集します
活動リストを補足します <activity android:name="com.inmobi.androidsdk.IMBrowserActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|smallestScreenSize|screenSize" android:theme="@android:style/Theme.Translucent.NoTitleBar"> </activity> <activity android:name="com.inmobi.android.sample.app.AdBannerActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|smallestScreenSize|screenSize" > </activity> <activity android:name="com.inmobi.android.sample.app.AdInterstitialActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|smallestScreenSize|screenSize"> </activity> <service android:name="com.inmobi.commons.internal.ActivityRecognitionManager" android:enabled="true"> </service> <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:theme="@android:style/Theme.Translucent" /> <meta-data android:name="com.google.android.gms.games.APP_ID" android:value="@string/gps_app_id" /> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> <activity android:name="com.chartboost.sdk.CBImpressionActivity" android:excludeFromRecents="true" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <activity android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:name="com.apptracker.android.module.AppModuleActivity" android:label="ModuleActivity" android:theme="@android:style/Theme.Translucent" > </activity> <receiver android:name="com.apptracker.android.track.AppTrackerReceiver" android:exported="true"> <intent-filter> <action android:name="com.android.vending.INSTALL_REFERRER" /> </intent-filter> </receiver>
許可のリストに追加する <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
ユースケース
- アプリケーションを初期化するとき、AdEngine_Init()を呼び出します。
- バナーをキャッシュする必要があるとき、AdEngine_Load()が呼び出されます。 技術的には、AdEngine_Show()メソッドを呼び出す前に何度も呼び出すことを妨げるものはありません。 メソッドAdEngine_Load()は、呼び出しの実際の頻度を調整する定数DELAY_MSを使用します。 また、このサービスのバナーが既にキャッシュされている場合、キャッシュ呼び出しは実際には発生しません。 アプリケーションをブロックする可能性があるため、サービスを頻繁に呼び出すことは推奨されません。
- バナーを表示する必要があるとき-AdEngine_Show()を呼び出します。
- AdEngine_Terminate()アプリケーションを閉じるときにセッションを閉じる。
使用経験
私のアプリケーションの主な配布エリアは、ロシア、ウクライナ、カザフスタン、ベラルーシです。 他の国もありますが、この割合はごくわずかです。 これらのサービスを1年間使用した結果、次の理由でInmobiとLeadboltを拒否しました。
- Leadboltは、クリックあたりの平均コストが非常に低いことを示しています(たとえば、AdMobと比較して)。
- InmobiのFillRateは低く、クリックスルー率も低くなっています。
ChartBoostには優れたFillRateがあるため、いくつかのAdMob(メインサービスとして)とChartBoost(AdMobのキャッシュ要求がエラーを返した場合)のために停止しました。
Appodealと統合する計画があります-すべてがうまくいけば、私は間違いなく記事を補足します。