简体   繁体   English

Mopub:使用适配器InMobiNative集成inmobi原生广告

[英]Mopub: integrating inmobi native ads with the adapter InMobiNative

It appears that the whole inmobi sdk has changed significantly from 4.4.1 to 5.2.3 which means that I cannot integrate the inmobi sdk successfully into mopub. 看来整个inmobi sdk已从4.4.1变为5.2.3,这意味着我无法将inmobi sdk成功集成到mopub中。 This is adapter bundled within the mopub sdk: 这是捆绑在mopub sdk中的适配器:

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

I have copied and pasted the code here for your convenience - you can see that the author has said that the adapter was tested on 4.4.1: 为方便起见,我在这里复制并粘贴了代码 - 您可以看到作者已经说过适配器已经在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();
        }
    }
}

Has anyone been successful in converting this adapter to work with the latest 5.2.3 inmobi sdk? 有没有人成功转换此适配器以使用最新的5.2.3 inmobi sdk?

The 4.4.1 sdk is not even available to download anymore and if there is no adapter for 5.2.3, then I'm afraid inmobi integration with in mopub is not possible? 4.4.1 sdk甚至无法下载,如果没有适用于5.2.3的适配器,那么恐怕无法与mopub集成inmobi吗?

I waited a few days and did not get any response back from Inmobi so I decided to do some investigation myself on how to solve this issue. 我等了几天,没有收到Inmobi的任何回复,所以我决定自己做些关于如何解决此问题的调查。 Eventually I can across this website which had a sample app with SDK 5.0.0 but the class seems to work with SDK 5.2.3 without any problems. 最终,我可以在这个网站上看到一个带有SDK 5.0.0的示例应用程序,但是该类似乎可以在SDK 5.2.3上正常使用。

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

I had to read the class and make my own adjustments to the adapter so that it will work - their adapter had issues as they were using deprecated classes. 我必须阅读该类并对适配器进行自己的调整以使其正常工作 - 它们的适配器因使用已弃用的类而出现问题。 So here is the updated adapter: 所以这是更新的适配器:

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);
                }
            });
        }


    }
}

Then you need to read this website telling you more about how to integrate their SDK into your app. 然后,您需要阅读此网站,告诉您有关如何将其SDK集成到您的应用程序的更多信息。 You need to copy and paste this into your manifest: 您需要将其复制并粘贴到清单中:

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

<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>

Without these classes, the SDK will not initialize and you will get an error in the logs. 如果没有这些类,SDK将不会初始化,您将在日志中收到错误。

Please do read through both websites, I'm just dealing on a high level on how you can solve the integration but there are other stuff you should put into your app to make mopub work successfully with inmobi for Android. 请仔细阅读这两个网站,我只是在处理如何解决集成问题的高级别问题,但是你应该在应用程序中添加其他东西,以使mopub成功地使用inmobi for Android。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM