[android] Implemented tracking the ads logic

This commit is contained in:
alexzatsepin 2017-03-24 19:04:45 +03:00 committed by Vladimir Byko-Ianko
parent b7650c297c
commit 871a8c7920
4 changed files with 59 additions and 27 deletions

View file

@ -2,7 +2,7 @@ package com.mapswithme.maps.ads;
import android.support.annotation.NonNull;
public interface AdTracker
interface AdTracker
{
void onViewShown(@NonNull String bannerId);
void onViewHidden(@NonNull String bannerId);

View file

@ -13,7 +13,7 @@ public class DefaultAdTracker implements AdTracker, OnAdCacheModifiedListener
{
private final static Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
private final static String TAG = DefaultAdTracker.class.getSimpleName();
private final static int GOOD_IMPRESSION_TIME_MS = 2000;
private final static int IMPRESSION_TIME_MS = 2000;
private final Map<String, TrackInfo> mTracks = new HashMap<>();
@Override
@ -21,8 +21,12 @@ public class DefaultAdTracker implements AdTracker, OnAdCacheModifiedListener
{
LOGGER.d(TAG, "onViewShown bannerId = " + bannerId);
TrackInfo info = mTracks.get(bannerId);
if (info != null)
info.setVisible(true);
if (info == null)
{
info = new TrackInfo();
mTracks.put(bannerId, info);
}
info.setVisible(true);
}
@Override
@ -30,8 +34,10 @@ public class DefaultAdTracker implements AdTracker, OnAdCacheModifiedListener
{
LOGGER.d(TAG, "onViewHidden bannerId = " + bannerId);
TrackInfo info = mTracks.get(bannerId);
if (info != null)
info.setVisible(false);
if (info == null)
throw new AssertionError("A track info cannot be null because this method " +
"is called only after onViewShown!");
info.setVisible(false);
}
@Override
@ -49,25 +55,34 @@ public class DefaultAdTracker implements AdTracker, OnAdCacheModifiedListener
public boolean isImpressionGood(@NonNull String bannerId)
{
TrackInfo info = mTracks.get(bannerId);
return info != null && info.getShowTime() > GOOD_IMPRESSION_TIME_MS;
return info != null && info.getShowTime() > IMPRESSION_TIME_MS;
}
@Override
public void onRemoved(@NonNull String id)
{
LOGGER.d(TAG, "onRemoved id = " + id);
mTracks.remove(id);
}
@Override
public void onPut(@NonNull String id)
{
LOGGER.d(TAG, "onPut id = " + id);
mTracks.put(id, new TrackInfo());
TrackInfo info = mTracks.get(id);
if (info == null)
{
mTracks.put(id, new TrackInfo());
return;
}
if (info.getShowTime() != 0)
info.setLastShow(true);
}
private static class TrackInfo
{
/**
* A timestamp to track ad visibility
*/
private long mTimestamp;
/**
* Accumulates amount of time that ad is already shown.
@ -82,44 +97,63 @@ public class DefaultAdTracker implements AdTracker, OnAdCacheModifiedListener
*/
private boolean mFilled;
public void setVisible(boolean visible)
/**
* Indicates whether it's the last time when an ad was shown or not.
*/
private boolean mLastShow;
void setVisible(boolean visible)
{
boolean wasVisible = mVisible;
mVisible = visible;
// No need tracking if the ad is not filled with a content
if (!mFilled)
return;
// If ad becomes visible, and it's filled with a content the timestamp must be stored.
if (visible && !mVisible)
if (visible && !wasVisible)
{
mTimestamp = SystemClock.elapsedRealtime();
}
// If ad is hidden the show time must be accumulated.
else if (!visible && mVisible)
else if (!visible && wasVisible)
{
if (mLastShow)
{
mShowTime = 0;
mTimestamp = 0;
mLastShow = false;
LOGGER.d(TAG, "it's a last time for this ad");
return;
}
mShowTime += SystemClock.elapsedRealtime() - mTimestamp;
mTimestamp = 0;
}
mVisible = visible;
}
boolean isVisible()
{
return mVisible;
}
public void fill()
{
// If the visible ad is filled with the content the timestamp must be stored
if (mVisible)
{
mTimestamp = SystemClock.elapsedRealtime();
}
mFilled = true;
}
private boolean isRealShow()
{
return mFilled && mVisible;
mFilled = true;
}
long getShowTime()
{
return mShowTime;
}
void setLastShow(boolean lastShow)
{
mLastShow = lastShow;
}
}
}

View file

@ -47,7 +47,7 @@ public class FacebookAdsLoader implements AdListener
* @param tracker An ad tracker
*/
@UiThread
public void load(@NonNull Context context, @NonNull String placementId, @NonNull AdTracker tracker)
public void load(@NonNull Context context, @NonNull String placementId, @Nullable AdTracker tracker)
{
LOGGER.d(TAG, "Load a facebook ad for a placement id '" + placementId + "'");
@ -60,7 +60,7 @@ public class FacebookAdsLoader implements AdListener
return;
}
if (tracker.isImpressionGood(placementId)
if (tracker != null && tracker.isImpressionGood(placementId)
&& SystemClock.elapsedRealtime() - cachedAd.getLoadedTime() >= REQUEST_INTERVAL_MS)
{
LOGGER.d(TAG, "A new ad will be loaded because the previous one has a good impression");
@ -204,7 +204,7 @@ public class FacebookAdsLoader implements AdListener
private static class FacebookAd
{
@NonNull
private NativeAd mAd;
private final NativeAd mAd;
private final long mLoadedTime;
FacebookAd(@NonNull NativeAd ad, long timestamp)

View file

@ -90,7 +90,6 @@ final class BannerController
mActionSmall = (TextView) bannerView.findViewById(R.id.tv__action_small);
mActionLarge = (TextView) bannerView.findViewById(R.id.tv__action_large);
mAds = bannerView.findViewById(R.id.tv__ads);
//TODO: pass as constructor arguments
mAdsLoader = new FacebookAdsLoader();
mAdsLoader.setAdsListener(new NativeAdsListener());
mAdTracker = new DefaultAdTracker();
@ -156,12 +155,11 @@ final class BannerController
void open()
{
if (!isBannerVisible() || mBanner == null || mOpened)
if (!isBannerVisible() || mBanner == null || TextUtils.isEmpty(mBanner.getId()) || mOpened)
return;
mOpened = true;
setFrameHeight(WRAP_CONTENT);
//FIXME NPE
NativeAd data = mAdsLoader.getAdByIdFromCache(mBanner.getId());
if (data != null)
loadIcon(data.getAdIcon());