Mopub:将inmobi原生广告与适配器InMobiNative集成



整个inmobi sdk似乎从4.4.1到5.2.3发生了显著变化,这意味着我无法将inmobi sdk成功集成到mopub中。这是捆绑在mopub-sdk:中的适配器

https://github.com/motain/android-ads-MoPub/blob/master/extras/src/com/mopub/nativeads/InMobiNative.java

为了方便您,我将代码复制并粘贴在这里——您可以看到,作者已经说过适配器在4.4.1上进行了测试:

package com.mopub.nativeads;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import com.inmobi.commons.InMobi;
import com.inmobi.monetization.IMErrorCode;
import com.inmobi.monetization.IMNative;
import com.inmobi.monetization.IMNativeListener;
import com.mopub.common.util.MoPubLog;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static com.mopub.common.util.Json.getJsonValue;
import static com.mopub.common.util.Numbers.parseDouble;
/*
 * Tested with InMobi SDK 4.4.1
 */
class InMobiNative extends CustomEventNative implements IMNativeListener {
    private static final String APP_ID_KEY = "app_id";
    private Context mContext;
    private CustomEventNativeListener mCustomEventNativeListener;
    // CustomEventNative implementation
    @Override
    protected void loadNativeAd(final Context context,
            final CustomEventNativeListener customEventNativeListener,
            final Map<String, Object> localExtras,
            final Map<String, String> serverExtras) {
        mContext = context;
        if (!(context instanceof Activity)) {
            customEventNativeListener.onNativeAdFailed(NativeErrorCode.NATIVE_ADAPTER_CONFIGURATION_ERROR);
            return;
        }
        final Activity activity = (Activity) context;
        final String appId;
        if (extrasAreValid(serverExtras)) {
            appId = serverExtras.get(APP_ID_KEY);
        } else {
            customEventNativeListener.onNativeAdFailed(NativeErrorCode.NATIVE_ADAPTER_CONFIGURATION_ERROR);
            return;
        }
        mCustomEventNativeListener = customEventNativeListener;
        InMobi.initialize(activity, appId);
        final IMNative imNative = new IMNative(this);
        imNative.loadAd();
    }
    // IMNativeListener implementation
    @Override
    public void onNativeRequestSucceeded(final IMNative imNative) {
        if (imNative == null) {
            mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_STATE);
            return;
        }
        final InMobiForwardingNativeAd inMobiForwardingNativeAd;
        try {
            inMobiForwardingNativeAd = new InMobiForwardingNativeAd(imNative);
        } catch (IllegalArgumentException e) {
            mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.UNSPECIFIED);
            return;
        } catch (JSONException e) {
            mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.INVALID_JSON);
            return;
        }
        final List<String> imageUrls = new ArrayList<String>();
        final String mainImageUrl = inMobiForwardingNativeAd.getMainImageUrl();
        if (mainImageUrl != null) {
            imageUrls.add(mainImageUrl);
        }
        final String iconUrl = inMobiForwardingNativeAd.getIconImageUrl();
        if (iconUrl != null) {
            imageUrls.add(iconUrl);
        }
        preCacheImages(mContext, imageUrls, new ImageListener() {
            @Override
            public void onImagesCached() {
                mCustomEventNativeListener.onNativeAdLoaded(inMobiForwardingNativeAd);
            }
            @Override
            public void onImagesFailedToCache(NativeErrorCode errorCode) {
                mCustomEventNativeListener.onNativeAdFailed(errorCode);
            }
        });
    }
    @Override
    public void onNativeRequestFailed(final IMErrorCode errorCode) {
        if (errorCode == IMErrorCode.INVALID_REQUEST) {
            mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_REQUEST);
        } else if (errorCode == IMErrorCode.INTERNAL_ERROR || errorCode == IMErrorCode.NETWORK_ERROR) {
            mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_STATE);
        } else if (errorCode == IMErrorCode.NO_FILL) {
            mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_NO_FILL);
        } else {
            mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.UNSPECIFIED);
        }
    }
    private boolean extrasAreValid(final Map<String, String> serverExtras) {
        final String placementId = serverExtras.get(APP_ID_KEY);
        return (placementId != null && placementId.length() > 0);
    }
    static class InMobiForwardingNativeAd extends BaseForwardingNativeAd {
        static final int IMPRESSION_MIN_TIME_VIEWED = 0;
        // Modifiable keys
        static final String TITLE = "title";
        static final String DESCRIPTION = "description";
        static final String SCREENSHOTS = "screenshots";
        static final String ICON = "icon";
        static final String LANDING_URL = "landing_url";
        static final String CTA = "cta";
        static final String RATING = "rating";
        // Constant keys
        static final String URL = "url";
        private final IMNative mImNative;
        InMobiForwardingNativeAd(final IMNative imNative) throws IllegalArgumentException, JSONException {
            if (imNative == null) {
                throw new IllegalArgumentException("InMobi Native Ad cannot be null");
            }
            mImNative = imNative;
            final JSONTokener jsonTokener = new JSONTokener(mImNative.getContent());
            final JSONObject jsonObject = new JSONObject(jsonTokener);
            setTitle(getJsonValue(jsonObject, TITLE, String.class));
            setText(getJsonValue(jsonObject, DESCRIPTION, String.class));
            final JSONObject screenShotJsonObject = getJsonValue(jsonObject, SCREENSHOTS, JSONObject.class);
            if (screenShotJsonObject != null) {
                setMainImageUrl(getJsonValue(screenShotJsonObject, URL, String.class));
            }
            final JSONObject iconJsonObject = getJsonValue(jsonObject, ICON, JSONObject.class);
            if (iconJsonObject != null) {
                setIconImageUrl(getJsonValue(iconJsonObject, URL, String.class));
            }
            setClickDestinationUrl(getJsonValue(jsonObject, LANDING_URL, String.class));
            setCallToAction(getJsonValue(jsonObject, CTA, String.class));
            try {
                setStarRating(parseDouble(jsonObject.opt(RATING)));
            } catch (ClassCastException e) {
                MoPubLog.d("Unable to set invalid star rating for InMobi Native.");
            }
            setImpressionMinTimeViewed(IMPRESSION_MIN_TIME_VIEWED);
        }
        @Override
        public void prepareImpression(final View view) {
            if (view != null && view instanceof ViewGroup) {
                mImNative.attachToView((ViewGroup) view);
            } else if (view != null && view.getParent() instanceof ViewGroup) {
                mImNative.attachToView((ViewGroup) view.getParent());
            } else {
                MoPubLog.e("InMobi did not receive ViewGroup to attachToView, unable to record impressions");
            }
        }
        @Override
        public void handleClick(final View view) {
            mImNative.handleClick(null);
        }
        @Override
        public void destroy() {
            mImNative.detachFromView();
        }
    }
}

是否有人成功地将此适配器转换为使用obi-sdk中的最新5.2.3?

4.4.1 sdk甚至不能再下载了,如果5.2.3没有适配器,那么恐怕inmobi与in-mopub的集成是不可能的?

我等了几天,没有收到Inmobi的任何回复,所以我决定自己调查一下如何解决这个问题。最终,我可以浏览这个网站,它有一个带有SDK 5.0.0的示例应用程序,但该类似乎可以使用SDK 5.2.3,没有任何问题。

https://support.inmobi.com/monetize/integration/mediation-adapters/mopub-adaptor-android-sdk-integration-guide/#getting-启动

我必须阅读这个类,并对适配器进行自己的调整,这样它才能工作——他们的适配器在使用不推荐使用的类时出现了问题。所以这里是更新的适配器:

package com.mopub.nativeads;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import com.inmobi.ads.InMobiAdRequestStatus;
import com.inmobi.sdk.InMobiSdk;
import com.mopub.common.MoPub;
import com.mopub.common.logging.MoPubLog;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.mopub.common.util.Json.getJsonValue;
import static com.mopub.common.util.Numbers.parseDouble;
import static com.mopub.nativeads.NativeImageHelper.preCacheImages;
/*
 * Tested with InMobi SDK 5.2.3
 */
public class InMobiNative extends CustomEventNative {

    private static boolean isAppIntialize = false;
    private JSONObject serverParams;
    private String accountId="XXX";
    private long placementId=123L;

    @Override
    protected void loadNativeAd(@NonNull Activity arg0,
                                @NonNull CustomEventNativeListener arg1,
                                @NonNull Map<String, Object> arg2,
                                @NonNull Map<String, String> arg3) {
        // TODO Auto-generated method stub
        Log.d("InMobiNativeCustomEvent", "Reached native adapter");
        try {
            serverParams = new JSONObject(arg3);
        } catch (Exception e) {
            Log.e("InMobi", "Could not parse server parameters");
            e.printStackTrace();
        }
        Activity activity = null;
        if (arg0 instanceof Activity) {
            activity = arg0;
        } else {
            // You may also pass in an Activity Context in the localExtras map
            // and retrieve it here.
        }
        if (activity == null) {
            arg1.onNativeAdFailed(NativeErrorCode.NATIVE_ADAPTER_CONFIGURATION_ERROR);
            return;
        }
        try {
            accountId = serverParams.getString("accountid");
            placementId = serverParams.getLong("placementId");
        } catch (JSONException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        if (!isAppIntialize) {
            try {
                InMobiSdk.init(activity,"accountid");
            } catch (Exception e) {
                e.printStackTrace();
            }
            isAppIntialize = true;
        }
        InMobiSdk.setAreaCode("areacode");
        InMobiSdk.setEducation(InMobiSdk.Education.HIGH_SCHOOL_OR_LESS);
        InMobiSdk.setGender(InMobiSdk.Gender.MALE);
        InMobiSdk.setIncome(1000);
        InMobiSdk.setAge(23);
        InMobiSdk.setPostalCode("postalcode");
        InMobiSdk.setLogLevel(InMobiSdk.LogLevel.DEBUG);
        InMobiSdk.setLocationWithCityStateCountry("blore", "kar", "india");
        InMobiSdk.setLanguage("ENG");
        InMobiSdk.setInterests("dance");
        InMobiSdk.setEthnicity(InMobiSdk.Ethnicity.ASIAN);
        InMobiSdk.setYearOfBirth(1980);
        Map<String, String> map = new HashMap<String, String>();
        map.put("tp", "c_mopub");
        map.put("tp-ver", MoPub.SDK_VERSION);
        final InMobiStaticNativeAd inMobiStaticNativeAd =
                new InMobiStaticNativeAd(arg0,
                        new ImpressionTracker(arg0),
                        new NativeClickHandler(arg0),
                        arg1);
        inMobiStaticNativeAd.setIMNative(new com.inmobi.ads.InMobiNative(placementId, inMobiStaticNativeAd));
        inMobiStaticNativeAd.setExtras(map);
        inMobiStaticNativeAd.loadAd();
    }

    static class InMobiStaticNativeAd extends StaticNativeAd implements com.inmobi.ads.InMobiNative.NativeAdListener {
        static final int IMPRESSION_MIN_TIME_VIEWED = 1000;
        // Modifiable keys
        static final String TITLE = "title";
        static final String DESCRIPTION = "description";
        static final String SCREENSHOTS = "screenshots";
        static final String ICON = "icon";
        static final String LANDING_URL = "landingURL";
        static final String CTA = "cta";
        static final String RATING = "rating";
        // Constant keys
        static final String URL = "url";
        private final Context mContext;
        private final CustomEventNativeListener mCustomEventNativeListener;
        private final ImpressionTracker mImpressionTracker;
        private final NativeClickHandler mNativeClickHandler;
        private com.inmobi.ads.InMobiNative mImNative;
        InMobiStaticNativeAd(final Context context,
                             final ImpressionTracker impressionTracker,
                             final NativeClickHandler nativeClickHandler,
                             final CustomEventNativeListener customEventNativeListener) {
            InMobiSdk.init(context,"9107a61fcda34c969d3f74934a352dcb");
            mContext = context.getApplicationContext();
            mImpressionTracker = impressionTracker;
            mNativeClickHandler = nativeClickHandler;
            mCustomEventNativeListener = customEventNativeListener;
        }
        void setIMNative(final com.inmobi.ads.InMobiNative imNative) {
            mImNative = imNative;
        }
        void setExtras(Map<String,String> map){
            mImNative.setExtras(map);
        }
        void loadAd() {
            mImNative.load();
        }

        // Lifecycle Handlers
        @Override
        public void prepare(final View view) {
            if (view != null && view instanceof ViewGroup) {
                com.inmobi.ads.InMobiNative.bind((ViewGroup)view, mImNative);
            } else if (view != null && view.getParent() instanceof ViewGroup) {
                com.inmobi.ads.InMobiNative.bind((ViewGroup)(view.getParent()), mImNative);
            } else {
                Log.e("MoPub", "InMobi did not receive ViewGroup to attachToView, unable to record impressions");
            }
            mImpressionTracker.addView(view, this);
            mNativeClickHandler.setOnClickListener(view, this);
        }
        @Override
        public void clear(final View view) {
            mImpressionTracker.removeView(view);
            mNativeClickHandler.clearOnClickListener(view);
        }
        @Override
        public void destroy() {
            //InMobiNative.unbind(arg0);
            mImpressionTracker.destroy();
        }
        // Event Handlers
        @Override
        public void recordImpression(final View view) {
            notifyAdImpressed();
        }
        @Override
        public void handleClick(final View view) {
            notifyAdClicked();
            mNativeClickHandler.openClickDestinationUrl(getClickDestinationUrl(), view);
            mImNative.reportAdClick(null);
        }
        void parseJson(final com.inmobi.ads.InMobiNative inMobiNative) throws JSONException  {
            final JSONTokener jsonTokener = new JSONTokener((String) inMobiNative.getAdContent());
            final JSONObject jsonObject = new JSONObject(jsonTokener);
            setTitle(getJsonValue(jsonObject, TITLE, String.class));
            String text = getJsonValue(jsonObject, DESCRIPTION, String.class);
            if(text!=null)
                setText(text);
            final JSONObject screenShotJsonObject = getJsonValue(jsonObject, SCREENSHOTS, JSONObject.class);
            if (screenShotJsonObject != null) {
                setMainImageUrl(getJsonValue(screenShotJsonObject, URL, String.class));
            }
            final JSONObject iconJsonObject = getJsonValue(jsonObject, ICON, JSONObject.class);
            if (iconJsonObject != null) {
                setIconImageUrl(getJsonValue(iconJsonObject, URL, String.class));
            }
            final String clickDestinationUrl = getJsonValue(jsonObject, LANDING_URL, String.class);
            if (clickDestinationUrl == null) {
                final String errorMessage = "InMobi JSON response missing required key: "
                        + LANDING_URL + ". Failing over.";
                MoPubLog.d(errorMessage);
                throw new JSONException(errorMessage);
            }
            setClickDestinationUrl(clickDestinationUrl);
            String cta = getJsonValue(jsonObject, CTA, String.class);
            if(cta!=null)
                setCallToAction(cta);
            try {
                if(jsonObject.opt(RATING)!=null){
                    setStarRating(parseDouble(jsonObject.opt(RATING)));
                }
            } catch (ClassCastException e) {
                Log.d("MoPub", "Unable to set invalid star rating for InMobi Native.");
            }            setImpressionMinTimeViewed(IMPRESSION_MIN_TIME_VIEWED);
        }
        @Override
        public void onAdDismissed(com.inmobi.ads.InMobiNative inMobiNative) {
            // TODO Auto-generated method stub
            Log.d("InMobiNativeCustomEvent","Native Ad is dismissed");
        }
        @Override
        public void onAdDisplayed(com.inmobi.ads.InMobiNative inMobiNative) {
            // TODO Auto-generated method stub
            Log.d("InMobiNativeCustomEvent","Native Ad is displayed");
        }
        @Override
        public void onAdLoadFailed(com.inmobi.ads.InMobiNative arg0, InMobiAdRequestStatus arg1) {
            // TODO Auto-generated method stub
            Log.d("InMobiNativeCustomEvent","Native ad failed to load");
            String errorMsg="";
            switch (arg1.getStatusCode()) {
                case INTERNAL_ERROR:
                    errorMsg="INTERNAL_ERROR";
                    break;
                case REQUEST_INVALID:
                    errorMsg="INVALID_REQUEST";
                    break;
                case NETWORK_UNREACHABLE:
                    errorMsg="NETWORK_UNREACHABLE";
                    break;
                case NO_FILL:
                    errorMsg="NO_FILL";
                    break;
                case REQUEST_PENDING:
                    errorMsg="REQUEST_PENDING";
                    break;
                case REQUEST_TIMED_OUT:
                    errorMsg="REQUEST_TIMED_OUT";
                    break;
                case SERVER_ERROR:
                    errorMsg="SERVER_ERROR";
                    break;
                case AD_ACTIVE:
                    errorMsg="AD_ACTIVE";
                    break;
                case EARLY_REFRESH_REQUEST:
                    errorMsg="EARLY_REFRESH_REQUEST";
                    break;
                default:
                    errorMsg="NETWORK_ERROR";
                    break;
            }
            if (errorMsg == "INVALID_REQUEST") {
                mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_REQUEST);
            } else if (errorMsg == "INTERNAL_ERROR" || errorMsg == "NETWORK_ERROR") {
                mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_STATE);
            } else if (errorMsg == "NO_FILL") {
                mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_NO_FILL);
            } else if (errorMsg == "REQUEST_TIMED_OUT"){
                mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_TIMEOUT);
            }else if(errorMsg == "NETWORK_UNREACHABLE"){
                mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.CONNECTION_ERROR);
            }
            else {
                mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.UNSPECIFIED);
            }
        }

        @Override
        public void onUserLeftApplication(com.inmobi.ads.InMobiNative arg0) {
            // TODO Auto-generated method stub
            Log.d("InMobiNativeCustomEvent","User left application");
        }
        @Override
        public void onAdLoadSucceeded(com.inmobi.ads.InMobiNative inMobiNative) {
            // TODO Auto-generated method stub
            Log.v("InMobiNativeCustomEvent", "Ad loaded:"+inMobiNative.getAdContent().toString());
            try {
                parseJson(inMobiNative);
            } catch (JSONException e) {
                mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.INVALID_RESPONSE);
                return;
            }
            final List<String> imageUrls = new ArrayList<String>();
            /*final String mainImageUrl = getMainImageUrl();
            if (mainImageUrl != null) {
                imageUrls.add(mainImageUrl);
            }*/
            final String iconUrl = getIconImageUrl();
            if (iconUrl != null) {
                imageUrls.add(iconUrl);
            }
            preCacheImages(mContext, imageUrls, new NativeImageHelper.ImageListener() {
                @Override
                public void onImagesCached() {
                    Log.v("InMobiNativeCustomEvent", "image cached");
                    mCustomEventNativeListener.onNativeAdLoaded(InMobiStaticNativeAd.this);
                }
                @Override
                public void onImagesFailedToCache(NativeErrorCode errorCode) {
                    Log.v("InMobiNativeCustomEvent", "image failed to cache");
                    mCustomEventNativeListener.onNativeAdFailed(errorCode);
                }
            });
        }

    }
}

然后你需要阅读这个网站,告诉你更多关于如何将他们的SDK集成到你的应用程序中的信息。您需要将其复制并粘贴到您的清单中:

https://support.inmobi.com/android-sdk-integration-guide/#getting-启动

<activity android:name="com.inmobi.rendering.InMobiAdActivity"
android:configChanges="keyboardHidden|orientation|keyboard|smallestScreenSize|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:hardwareAccelerated="true" />
<receiver
android:name="com.inmobi.commons.core.utilities.uid.ImIdShareBroadCastReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="com.inmobi.share.id" />
</intent-filter>
</receiver>

如果没有这些类,SDK将无法初始化,并且日志中会出现错误。

请仔细阅读这两个网站,我只是在谈论如何解决集成,但还有其他东西你应该放进你的应用程序中,以使mopub在inmobi for Android中成功工作。

最新更新