2
votes

I was trying to integrate both Google pay services and Admob together in my Android game developing in Cocos2dx. But I'm getting this error

Unable to execute dex: Multiple dex files define Lcom/google/ads/AdRequest$ErrorCode; Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lcom/google/ads/AdRequest$ErrorCode;

1

1 Answers

4
votes

I was also facing the same problem..This is due to conflict between google-play-services and GoogleAdMobAdsSdk....Here is the solution I found atlast. Update your google-play-services library. Goto your project/cocos2d/plugin/plugins/admob/proj.android/src/org/cocos2dx/plugin/

Modify the file AdsAdmob.java to

 package org.cocos2dx.plugin;

import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

//import com.google.ads.*;
//import com.google.android.gms.ads.AdRequest.ErrorCode;
import com.google.android.gms.ads.*;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.WindowManager;

public class AdsAdmob implements InterfaceAds{

private static final String LOG_TAG = "AdsAdmob";
private static Activity mContext = null;
private static boolean bDebug = false;
private static AdsAdmob mAdapter = null;

private AdView adView = null;
private String mPublishID = "";
private Set<String> mTestDevices = null;
private WindowManager mWm = null;

private static final int ADMOB_SIZE_BANNER = 1;
private static final int ADMOB_SIZE_IABMRect = 2;
private static final int ADMOB_SIZE_IABBanner = 3;
private static final int ADMOB_SIZE_IABLeaderboard = 4;
private static final int ADMOB_SIZE_Skyscraper = 5;

private static final int ADMOB_TYPE_BANNER = 1;
private static final int ADMOB_TYPE_FULLSCREEN = 2;

protected static void LogE(String msg, Exception e) {
    Log.e(LOG_TAG, msg, e);
    e.printStackTrace();
}

protected static void LogD(String msg) {
    if (bDebug) {
        Log.d(LOG_TAG, msg);
    }
}

public AdsAdmob(Context context) {
    mContext = (Activity) context;
    mAdapter = this;
}

@Override
public void setDebugMode(boolean debug) {
    bDebug = debug;
}

@Override
public String getSDKVersion() {
    return "6.3.1";
}

@Override
public void configDeveloperInfo(Hashtable<String, String> devInfo) {
    try {
        mPublishID = devInfo.get("AdmobID");
        LogD("init AppInfo : " + mPublishID);
    } catch (Exception e) {
        LogE("initAppInfo, The format of appInfo is wrong", e);
    }
}

@Override
public void showAds(Hashtable<String, String> info, int pos) {
    try
    {
        String strType = info.get("AdmobType");
        int adsType = Integer.parseInt(strType);

        switch (adsType) {
            case ADMOB_TYPE_BANNER:
            {
                String strSize = info.get("AdmobSizeEnum");
                int sizeEnum = Integer.parseInt(strSize);
                showBannerAd(sizeEnum, pos);
                break;
            }
            case ADMOB_TYPE_FULLSCREEN:
                LogD("Now not support full screen view in Admob");
                break;
            default:
                break;
        }
    } catch (Exception e) {
        LogE("Error when show Ads ( " + info.toString() + " )", e);
    }
}

@Override
public void spendPoints(int points) {
    LogD("Admob not support spend points!");
}

@Override
public void hideAds(Hashtable<String, String> info) {
    try
    {
        String strType = info.get("AdmobType");
        int adsType = Integer.parseInt(strType);

        switch (adsType) {
            case ADMOB_TYPE_BANNER:
                hideBannerAd();
                break;
            case ADMOB_TYPE_FULLSCREEN:
                LogD("Now not support full screen view in Admob");
                break;
            default:
                break;
        }
    } catch (Exception e) {
        LogE("Error when hide Ads ( " + info.toString() + " )", e);
    }
}

private void showBannerAd(int sizeEnum, int pos) {
    final int curPos = pos;
    final int curSize = sizeEnum;

    PluginWrapper.runOnMainThread(new Runnable() {

        @Override
        public void run() {
            // destory the ad view before
            if (null != adView) {
                if (null != mWm) {
                    mWm.removeView(adView);
                }
                adView.destroy();
                adView = null;
            }

            AdSize size = AdSize.BANNER;
            switch (curSize) {
                case AdsAdmob.ADMOB_SIZE_BANNER:
                    size = AdSize.BANNER;
                    break;
                    //                case AdsAdmob.ADMOB_SIZE_IABMRect:
                    //                    size = AdSize.IAB_MRECT;
                    //                    break;
                    //                case AdsAdmob.ADMOB_SIZE_IABBanner:
                    //                    size = AdSize.IAB_BANNER;
                    //                    break;
                    //                case AdsAdmob.ADMOB_SIZE_IABLeaderboard:
                    //                    size = AdSize.IAB_LEADERBOARD;
                    //                    break;
                    //                case AdsAdmob.ADMOB_SIZE_Skyscraper:
                    //                    size = AdSize.IAB_WIDE_SKYSCRAPER;
                    //                    break;
                default:
                    break;
            }
            adView = new AdView(mContext);
            adView.setAdUnitId(mPublishID);
            adView.setAdSize(AdSize.BANNER);
            AdRequest adRequest= new AdRequest.Builder().build();
            adView.loadAd(adRequest);



            //adView = new AdView(mContext, size, mPublishID);
            //AdRequest req = new AdRequest();

            //                try {
            //                    if (mTestDevices != null) {
            //                        Iterator<String> ir = mTestDevices.iterator();
            //                        while(ir.hasNext())
            //                        {
            //                            request.addTestDevice(ir.next());
            //                        }
            //                    }
            //                } catch (Exception e) {
            //                    LogE("Error during add test device", e);
            //                }
            //
            //                adView.loadAd(request);
            ////                adView.setAdListener(new AdmobAdsListener());
            //
                            if (null == mWm) {
                                mWm = (WindowManager) mContext.getSystemService("window");
                            }
            AdsWrapper.addAdView(mWm, adView, curPos);
        }
    });
}

private void hideBannerAd() {
    PluginWrapper.runOnMainThread(new Runnable() {
        @Override
        public void run() {
            if (null != adView) {
                if (null != mWm) {
                    mWm.removeView(adView);
                }
                adView.destroy();
                adView = null;
            }
        }
    });
}

public void addTestDevice(String deviceID) {
    LogD("addTestDevice invoked : " + deviceID);
    if (null == mTestDevices) {
        mTestDevices = new HashSet<String>();
    }
    mTestDevices.add(deviceID);
}

@Override
public String getPluginVersion() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void queryPoints() {
    // TODO Auto-generated method stub

}

//    private class AdmobAdsListener implements A {
//
//        @Override
//        public void onDismissScreen(Ad arg0) {
//            LogD("onDismissScreen invoked");
//            AdsWrapper.onAdsResult(mAdapter, AdsWrapper.RESULT_CODE_AdsDismissed, "Ads view dismissed!");
//        }
//
//        @Override
//        public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
//            int errorNo = AdsWrapper.RESULT_CODE_UnknownError;
//            String errorMsg = "Unknow error";
//            switch (arg1) {
//            case NETWORK_ERROR:
//                errorNo =  AdsWrapper.RESULT_CODE_NetworkError;
//                errorMsg = "Network error";
//                break;
//            case INVALID_REQUEST:
//                errorNo = AdsWrapper.RESULT_CODE_NetworkError;
//                errorMsg = "The ad request is invalid";
//                break;
//            case NO_FILL:
//                errorMsg = "The ad request is successful, but no ad was returned due to lack of ad inventory.";
//                break;
//            default:
//                break;
//            }
//            LogD("failed to receive ad : " + errorNo + " , " + errorMsg);
//            AdsWrapper.onAdsResult(mAdapter, errorNo, errorMsg);
//        }
//
//        @Override
//        public void onLeaveApplication(Ad arg0) {
//            LogD("onLeaveApplication invoked");
//        }
//
//        @Override
//        public void onPresentScreen(Ad arg0) {
//            LogD("onPresentScreen invoked");
//            AdsWrapper.onAdsResult(mAdapter, AdsWrapper.RESULT_CODE_AdsShown, "Ads view shown!");
//        }
//
//        @Override
//        public void onReceiveAd(Ad arg0) {
//            LogD("onReceiveAd invoked");
//            AdsWrapper.onAdsResult(mAdapter, AdsWrapper.RESULT_CODE_AdsReceived, "Ads request received success!");
//        }
//    }
//
//    @Override
//    public String getPluginVersion() {
//        return "0.2.0";
//    }
//
//    @Override
//    public void queryPoints() {
//        LogD("Admob not support query points!");
//    }

}

This file is modified to use ad classes from google-play-services.jar. Then goto project/cocos2d/plugin/plugins/admob/proj.android/sdk and replace GoogleAdMobAdsSdk.jar with google-play-services.jar (you will get it from google-play-services library).

Then you may run publish.sh and then gameDevGuide.sh

Later on, remove google-play-services.jar from project properties->java build path ->libraries

Also,You can use this code to load banners in your .cpp file

 auto adMob = dynamic_cast<cocos2d::plugin::ProtocolAds*>(cocos2d::plugin::PluginManager::getInstance()->loadPlugin("AdsAdmob"));
    std::map<std::string,std::string> developer_info;
    std::map<std::string,std::string> ad_info;

    developer_info["AdmobID"] = "YOUR_ID";
    ad_info["AdmobType"] = "1";
    ad_info["AdmobSizeEnum"] = "1";
    adMob->configDeveloperInfo(developer_info);

    adMob->setDebugMode(true);
    cocos2d::plugin::ProtocolAds::AdsPos posAdmob = cocos2d::plugin::ProtocolAds::kPosBottom;
    adMob->showAds(ad_info,posAdmob);

Now build...This works for me..All the best!!