ページへ戻る

− Links

 印刷 

AndroidでのAdmobのANEの作成_Android側の作成 のバックアップソース(No.9) :: NJF Wiki

xpwiki:AndroidでのAdmobのANEの作成_Android側の作成 のバックアップソース(No.9)

« Prev[5]  Next »[6]
*導入 [#u13bdaeb]
まず、通常のAndroidアプリで広告を表示できないとANEを作成することはできません。ここではAndroidアプリでAdmobの広告を表示し、そこから必要なファイルを抜き出す方法を紹介します。

こちらの内容は「[[AndroidでのANEの作成/Android側の作成]]」にそった方法で行いますので、そちらも参考にして下さい。

また、こちらではAdmobの広告IDを使いますので、あらかじめテスト用のAndroidのアプリの登録とそのID、バナー広告用のID、インタースティシャル広告のIDを用意しておいて下さい。

*プロジェクトの作成 [#ad273fc2]

最初にAndroid Studioでプロジェクトの作成を行います。

&ref(admobNewProject.jpg,mw:480,mh:360);

名前は好きな物でかまいません。

次のターゲットは「Phone and Tablet」として、Minimum SDKは特に理由が無ければAPI10にしておくと良いでしょう。

&ref(admobTarget.jpg,mw:480,mh:360);

次のActivityは余計なものが無い方がやりやすいので「Empty Activity」にしておきます。

&ref(admobActivity.jpg,mw:480,mh:360);

Activityの名前はそのままMainActivityにしておきます。

&ref(admobActivityCustomize.jpg,mw:480,mh:360);

「Finish」ボタンを押すとプロジェクトが作成されます。

*テスト用ボタンの作成 [#i8d2c989]

動作確認を行うためのテスト用ボタンを配置します。

「[[AndroidでのAdmobのANEの作成]]」でも説明したように、このANEには以下の機能があります。

-各種IDの設定
-バナー広告の表示
-バナー広告の非表示
-インタースティシャル広告のロード
-インタースティシャル広告の表示

このうち最初の「各種IDの設定」については内部的に一度行うだけのもので、インタラクティブである必要はありません。

よって残りの4つについて、それぞれの機能を確認できるように4つボタンを配置します。

ボタン配置方法の詳細は[[こちらの記事で:http://njf.jp/cms/modules/xpwiki/?Android%E3%81%A7%E3%81%AEANE%E3%81%AE%E4%BD%9C%E6%88%901_Android%E5%81%B4%E3%81%AE%E4%BD%9C%E6%88%90#gf75d92b]]ご紹介しているので、ここでは結果だけを表示します。

&ref(admobTestBtns.jpg,mw:480,mh:360);

ちょっとずれていますが、Androidのレイアウト調整は結構面倒なのでテスト用と割り切って細かな配置などにはこだわらないでおくのがお勧めです。

それぞれ以下のようにテキストとIDを割り振っています。

|ID|テキスト|
|showBannerBtn|SHOW BANNER|
|hideBannerBtn|HIDE BANNER|
|loadInterstitialBtn|LOAD INTER|
|showInterstitialBtn|SHOW INTER|

*ANE用のライブラリの作成 [#qcd3a06a]

次にテスト用のActivityなどと主処理を分離するために、ライブラリを作成します。

File->New->New Moduleを選択します。

&ref(admobNewModule.jpg,mw:480,mh:360);

Android Libraryを選びます。

&ref(admobNewLibrary.jpg,mw:480,mh:360);

名前はANEAdmobとしておきます。

&ref(admobLibraryName.jpg,mw:480,mh:360);

Finishボタンを押せばライブラリが作成されます。

*Google Play Servicesの追加 [#ua4e58f1]

(この部分については[[公式ページ:https://developers.google.com/mobile-ads-sdk/docs/admob/android/quick-start?hl=ja]]も参考にして下さい。)

Admobの表示にはGoogle Play Servicesが必要です。それを使えるようにするために、まずAndroid Studioで「Tools->Android->SDK Manager」を選択し、さらにSDK Toolsタブを選び、「Google Play Services」と「Google Repository」にチェックを入れます。

&ref(admobGooglePlayServiceUpdate.jpg,mw:480,mh:360);

すると次回起動時などにそれらも自動更新されます。

すぐにインストールやアップデートしたい場合は、ウインドウ下部に「Launch Standalone SDK Manager」というリンクがあるので、そこからスタンドアロン版SDKマネージャーを立ち上げてインストールまたはアップデートして下さい。

次にaneadmobのライブラリの中のbuild.gradleのdependenciesに「play-services-ads」を加えます。

&ref(admobBuildGradle.jpg,mw:480,mh:360);

例えばver.9.2.1なら

 compile 'com.google.android.gms:play-services-ads:9.2.1'

とします。

または

 compile 'com.google.android.gms:play-services-ads:9.+'

とすると、ver.9で一番新しいものが使われます。

ただし、ANEの製作では後でGoogle Play Servicesのバージョン番号を使うので、この記法よりもバージョンを明記しておいたほうがトラブルが起こりにくく、こちらの「+」を使った表記はあまりおすすめしません。(マイナーバージョンの違いのみなのでさほど問題は起こらないとは思いますが。)

build.gradleはあちこちにありますが、aneadmobの下のものなので間違えないようにして下さい。
するとdependencies部分はバージョン部分を除いて以下のようになります。

 dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.google.android.gms:play-services-ads:9.2.1'
 }

あとは「Sync Now」という表示が出ていると思うので、それをクリックしてgradleファイルの内容をプロジェクトに反映させれば、Admobの広告表示に必要なライブラリの取り込みができます。

*主処理の追加 [#o254a294]

広告表示の主処理となる部分を作っていきますが、あとでANEとして分離させないといけないので、サンプルなどにあるようにActivityに直接処理を書くわけにはいきません。admobaneライブラリの中に別クラスを作ってそこに主処理を書きます。

一方、Activityの方は、それを呼び出すテスト用のコードのみになるようにします。

まず
「aneadmob->src->main->java->jp.njf.admob」の下にANEAdmobというクラスを作成します。

&ref(admobANEAdmobClass.jpg,mw:480,mh:360);

前述しましたが、このANEには以下の機能を実装予定です。

-各種IDの設定
-バナー広告の表示
-バナー広告の非表示
-インタースティシャル広告のロード
-インタースティシャル広告の表示

最初の「各種ID」とは、AdmobのアプリケーションID、バナーID、インタースティシャルIDの3つです。

よってこのクラスには以下のpublicなメソッドが必要です。

|メソッド名|引数|機能|
|setAppID|アプリケーションID(String型)|アプリケーションIDを設定する|
|setBannerID|バナーの広告ID(String型)|バナーの広告IDを設定する|
|setInterstitialID|インタースティシャルの広告ID(String型)|インタースティシャルの広告IDを設定する|
|showBanner|なし|バナー広告の表示|
|hideBanner|なし|バナー広告の非表示|
|loadInterstitial|なし|インタースティシャル広告のロード|
|showInterstitial|なし|インタースティシャル広告の表示|

戻り値は全てなし、つまりvoid型メソッドです。

ここで「インタースティシャル広告のロード」については説明が必要かも知れません。インタースティシャル広告は全画面で表示され、場合によっては動画なども含まれるため、データ容量が大きく、ネットから広告データをロードするのに時間がかかります。
それを素早く表示するためには、あらかじめロードしておいて、それが完了していたら表示する、という手順をふむことになります。ロードの直後にすぐ表示しようとすると、ロードが終わっていないのでたいてい失敗します。

例えば、画面遷移5回毎に表示するなら一回目でロードし、4回も画面遷移すれば多分ロードは終わっているでしょうから、5回目の画面遷移で広告を表示する、といったふうに使います。そのため、ロードと表示のメソッドは分けておく必要があるのです。

ではクラスの詳細を解説します。
まずコンストラクタは広告の初期化で必要なactivityを引数とします。

 public ANEAdmob(Activity activity){
        this.activity = activity;
 }

次にアプリケーションのIDを設定するメソッドです。これは広告を表示する前であることはもちろん、他のIDを設定する前に必ず一度実行する必要があります。

    public void setAppID(String appID){
        MobileAds.initialize(activity, appID);
    }

次にバナーのIDを設定する関数です。
バナーの初期化も行い、かつアプリの下の中心に表示するようにしています。

    public void setBannerID(String bannerID){
        if(bannerView == null) {
            bannerView = new AdView(activity);
            bannerView.setAdUnitId(bannerID);
            bannerView.setVisibility(AdView.GONE);
            bannerView.setAdSize(AdSize.BANNER);
            FrameLayout.LayoutParams adLayout = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
            adLayout.gravity = Gravity.BOTTOM | Gravity.CENTER;
            FrameLayout.LayoutParams adParams = adLayout;
            activity.addContentView(bannerView, adParams);
            bannerView.setBackgroundColor(Color.BLACK);
        }
    }
バナーが二つ表示されるとやっかいなので、一度しか初期化できないようにif文でくくられています。
ここでsetBackgroundColorを使って背景色を黒にしています。
これはまれに広告のロードが終わっても画像が表示されず、透明のままになることがあり、するとユーザーの誤クリックを誘発しやすくなることを防ぐためです。
誤クリックが多いと、Admobはアカウント停止になる場合もあります。
Admobは特にバナーの規約が厳しいので、アプリのどこにどう表示するかは必ず規約を確認して下さい。
詳しくは「[[AdMob実装時の注意点]]」でも書いています。


バナーの表示と非表示はバナーの更新を止めて、viewのvisibilityを切り替えるだけです。

    public void showBanner(){
        if(bannerView.getVisibility() == AdView.VISIBLE){
            return;
        }
        bannerView.setVisibility(AdView.VISIBLE);
        bannerView.resume();
        bannerView.loadAd(makeAdRequest());
    }

    public void hideBanner(){
        if(bannerView.getVisibility() == AdView.GONE){
            return;
        }
        bannerView.pause();
        bannerView.setVisibility(AdView.GONE);
    }

通常、バナー広告は数十秒〜数分ごとに更新されます。
AdViewのpauseメソッドはこの更新を止めます。
バナーを消すと更新は不要なので呼び出しています。

アプリがバックグラウンドにまわったときも、余計な負荷を除くため、このpauseメソッドを呼び出し、再び前にまわったらresumeメソッドを呼び出すことをお勧めします。

ここの例では、単にバックグラウンドでhideBannerを、前にきたらshowBannerを呼び出すと良いでしょう。


ここでmakeAdRequestメソッドは広告用のリクエストを作るメソッドです。

    private AdRequest makeAdRequest() {
        return new AdRequest.Builder().build();
    }

一行しかありませんが、インタースティシャル広告でも使うのでメソッドにしています。また、AdRequestの作り方を
 return new AdRequest.Builder().addTestDevice("デバイスID").build();
とするとテスト用の広告が表示されるようになります。
「デバイスID」の部分はlogcatに
 I/Ads: Use AdRequest.Builder.addTestDevice("デバイスID") to get test ads on this device.
といった感じで表示されるので探してみて下さい。

Admobは開発者が自ら広告をタップしたり、開発時に実際の広告を表示するのを禁止しています。
現実的には少々テストで表示したり、一度や二度ほどタップしたからいきなり問題が生じることはありませんが、何度も表示したり誤タップしてしまうとアカウント停止などのなんらかのペナルティがある可能性があります。
そのため、テスト時にはこのようにテスト用デバイスを設定することをお勧めします。
また、その時のためにこのようにAdRequestを作成するメソッドは別に用意しておいた方が、一カ所直せば良いので便利です。

インタースティシャルの方は簡単です。

    public void setInterstitialID(String interstitialID){
        interstitial = new InterstitialAd(activity);
        interstitial.setAdUnitId(interstitialID);
    }


    public void loadInterstitial(){
        interstitial.loadAd(makeAdRequest());
    }

    public void showInterstitial(){
        if(interstitial.isLoaded()){
            interstitial.show();
        }
    }

isLoadedはロード完了かどうかを判定するメソッドです。

インタースティシャルは規約的にも注意するのは表示させすぎないぐらいで、それほど難しい部分はありません。

*Androidアプリとしてのテスト [#w2a72b1c]

次にANEAdmobクラスをAndroidでテストします。
まずappの下のbuild.gradleに次の一行を加えます。

 compile project(':aneadmob')

さらにapp/src/main/AndroidManifest.xmlに次のパーミッションを加えます。

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

同じくAndroidManifest.xmlのapplicationタグの中に次を入れます。

        <meta-data android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity android:name="com.google.android.gms.ads.AdActivity"            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
            android:theme="@android:style/Theme.Translucent" />



あとはonCreateメソッドにボタンを押したときの処理を入れます。

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);

         aneAdmob = new ANEAdmob(this);

         aneAdmob.setAppID(APP_ID);
         aneAdmob.setBannerID(BANNER_ID);
         aneAdmob.setInterstitialID(INTER_ID);

         Button button = (Button) findViewById(R.id.showBannerBtn);

         assert button != null;
         button.setOnClickListener(new View.OnClickListener() {
                                       @Override
                                       public void onClick(View v) {
                                           aneAdmob.showBanner();
                                       }

                                   }
         );

         button = (Button) findViewById(R.id.hideBannerBtn);

         assert button != null;
         button.setOnClickListener(new View.OnClickListener() {
                                       @Override
                                       public void onClick(View v) {
                                           aneAdmob.hideBanner();
                                       }

                                   }
         );
         button = (Button) findViewById(R.id.loadInterstitialBtn);

         assert button != null;
         button.setOnClickListener(new View.OnClickListener() {
                                       @Override
                                       public void onClick(View v) {
                                           aneAdmob.loadInterstitial();
                                       }

                                   }
         );

         button = (Button) findViewById(R.id.showInterstitialBtn);

         assert button != null;
         button.setOnClickListener(new View.OnClickListener() {
                                       @Override
                                       public void onClick(View v) {
                                           aneAdmob.showInterstitial();
                                       }

                                   }
         );

     }

これでテスト可能です。

これで動かないと当然ながらANEにしたところで動きません。ANEへの変換は手間がかかるので、作業を能率化するにはこの段階で入念にテストしておく必要があります。

*ANE呼び出し処理の追加 [#i5cd3b6c]

Android上で問題なく実行されたら、ANEにするための処理を入れます。

[[こちらを参考に:http://njf.jp/cms/modules/xpwiki/?Android%E3%81%A7%E3%81%AEANE%E3%81%AE%E4%BD%9C%E6%88%90%2FAndroid%E5%81%B4%E3%81%AE%E4%BD%9C%E6%88%90#a17e7947]]FlashRuntimeExtensions.jarをaneadmobの下のlibに配置します。

最終的にaneadmobのbuild.gradleのdependencies以下に次の一行が挿入されていればOKです。

 compile files('libs/FlashRuntimeExtensions.jar')

次にActionScriptから呼び出される部分を作ります。

呼び出しには次の二つのクラスが必要です。

|名前|機能|インターフェイス|
|ANEAdmobFREExtension|呼び出しの定義と振り分け処理|FREExtension|
|ANEAdmobFREFunction|実際に呼び出される関数|FREFunction|

ここではこれらのクラスをjp.njf.aneadmobパッケージとして制作します。

ここで呼び出されるクラスの設計には二つの選択肢があります。
呼び出される関数はFREFunctionをimplementsしておくと、その中のcallメソッドが呼ばれます。

よって呼び出しメソッドの数だけクラスを作るか、一つのクラスを作って内部的に振り分けるか、という設計があり得ます。

前節のように、このANEには7つのメソッドがあるので、7つもクラスを作るのは面倒です。よって一つのクラスを作って第一引数を使って処理の分岐を行うようにします。そのクラスが上記のANEAdmobFREFunctionで、メソッドの数だけクラスがないのはそのためです。

ただし、メソッドごとにクラスを作った方が呼び出しエラーなどがFlash側のtraceメッセージなどと一緒に表示されるため、デバッグは楽です。自分で振り分けする場合は、もちろん自分でエラー処理もしなくてはなりません。

このように一長一短ありますので、場合に応じて設計を変えて下さい。



まずANEAdmobFREExtensionクラスのcreateContextメソッドです。"admob"という名前で呼び出せるようにしておきます。

    @Override
    public FREContext createContext(String s) {
        FREContext context = new FREContext() {
            @Override
            public Map<String, FREFunction> getFunctions() {
                Map<String, FREFunction> result = new HashMap<String, FREFunction>();
                result.put("admob", new ANEAdmobFREFunction());
                return result;
            }

            @Override
            public void dispose() {

            }
        };
        return context;
    }

特に難しい部分はないはずです。分からない部分があれば「[[AndroidでのANEの作成/Android側の作成]]」を参照してください。

次にANEAdmobFREFunctionのcallメソッドです。
第一引数をメソッドの振り分けに、第二引数をパラメータとして使っています。

    public FREObject call(FREContext freContext, FREObject[] freObjects) {
        String method = "";
        String prm = "";
        try {
            method = freObjects[0].getAsString();
        } catch (Exception e) {
            Log.e("njf.jp.aneadmob", "ANEAdmobFREFunction:can't parse : arg 0");
        }
        try {
            prm = freObjects[1].getAsString();
        } catch (Exception e) {
            Log.w("njf.jp.aneadmob", "ANEAdmobFREFunction:can't parse : arg 1");
        }

        if(aneAdmob == null){
            aneAdmob = new ANEAdmob(freContext.getActivity());
        }

        if(method.equals("setAppID") && !prm.equals("")){
            aneAdmob.setAppID(prm);
        }else if(method.equals("setBannerID") && !prm.equals("")){
            aneAdmob.setBannerID(prm);
        }else if(method.equals("setInterstitialID") && !prm.equals("")){
            aneAdmob.setInterstitialID(prm);
        }else if(method.equals("showBanner")){
            aneAdmob.showBanner();
        }else if(method.equals("hideBanner")){
            aneAdmob.hideBanner();
        }else if(method.equals("showInterstitial")){
            aneAdmob.showInterstitial();
        }else if(method.equals("loadInterstitial")){
            aneAdmob.loadInterstitial();
        }else{
            Log.e("njf.jp.aneadmob", "ANEAdmobFREFunction:no method or invalid prm " + method);
        }
        return null;
    }


こちらも分からない部分があれば「[[AndroidでのANEの作成/Android側の作成]]」を参照してください。

*jarファイルの取り出し [#re49287b]

jarファイルの取り出しについては、[[こちらの記事:http://njf.jp/cms/modules/xpwiki/?Android%E3%81%A7%E3%81%AEANE%E3%81%AE%E4%BD%9C%E6%88%90%2FAndroid%E5%81%B4%E3%81%AE%E4%BD%9C%E6%88%90#veeed4bc]]と同じです。

ツールバーの「Build->Rebuild Project」でビルドし直して、aneadmob-release.aarファイルを探し出し、zip解凍してください。必要なのは「classes.jar」のみです。

----
-[[AndroidでのAdmobのANEの作成]]にもどる
-[[AndroidでのAdmobのANEの作成_swcの作成]]に進む


« Prev[5]  Next »[6]