Monday, July 18, 2016

Known issues as of Google Play Services 9.2

  1. NullPointerException: at com.google.android.gms.common.internal.zzi.onClick.
    For details see here for work around:
    http://stackoverflow.com/questions/38166820/google-play-services-9-2-0-causes-undesired-crash-in-device-without-google-play
     
  2.  NullPointerException: Attempt to invoke virtual method 'byte[] java.lang.String.getBytes()' on a null object reference android.util.Base64.decode.
    For details see here (no work around):
    http://stackoverflow.com/questions/37361651/firebase-crash-library-nullpointerexception-in-the-console

Thursday, December 17, 2015

Selecting native animation view

When creating an Android native (non-OpenGL) animation on a view, there are few options:
  • SurfaceView
  • TextureView (Android 4.0+)
  • View
While in Android 2.x SurfaceView was the best way, things changed. I'll skip to the bottom line: to my opinion as of Android 6.0 the best was is to override View. The reason is that both SurfaceView & TextureView do not support Android's hardware acceleration.

Hardware accelerated View is over x4 faster than SurfaceView & TextureView.

Sunday, June 7, 2015

AdMob interstial adapter for Appnext

I needed intergration Appnext into AdMob mediation bt there was not AdMob adapter, so I wrote one. Please note this adapter uses Appnext's Activities & not in-activity popups.


package com.appnext.appnextsdk;

import android.content.Context;
import android.os.Bundle;

import com.google.android.gms.ads.mediation.MediationAdRequest;
import com.google.android.gms.ads.mediation.customevent.CustomEventInterstitial;
import com.google.android.gms.ads.mediation.customevent.CustomEventInterstitialListener;

public class AppnextAdMobAdapter implements CustomEventInterstitial {
 private CustomEventInterstitialListener mCustomEventInterstitialListener;
 private String mPlacementId;
 private Context mContext;
 
 @Override
 public void onDestroy() {
 }

 @Override
 public void onPause() {
 }

 @Override
 public void onResume() {
 }

 @Override
 public void requestInterstitialAd(Context context,
            CustomEventInterstitialListener listener,
            String serverParameter,
            MediationAdRequest mediationAdRequest,
            Bundle customEventExtras) {
  mContext = context;
  mPlacementId = serverParameter;
  mCustomEventInterstitialListener = listener;

  if (mCustomEventInterstitialListener != null)
   mCustomEventInterstitialListener.onAdLoaded();
 }

 @Override
 public void showInterstitial() {
  PopupActivity.setAdLoadInterface(new OnAdLoadInterface() {   
   @Override
   public void adLoaded() {
    if (mCustomEventInterstitialListener != null)
     mCustomEventInterstitialListener.onAdLoaded();
   }
  });
  PopupActivity.setNoAdsInterface(new NoAdsInterface() {   
   @Override
   public void noAds() {
    if (mCustomEventInterstitialListener != null)
     mCustomEventInterstitialListener.onAdFailedToLoad(0);
   }
  });
  PopupActivity.setPopupOpenedInterface(new PopupOpenedInterface() {   
   @Override
   public void popupOpened() {
    if (mCustomEventInterstitialListener != null)
     mCustomEventInterstitialListener.onAdOpened();
   }
  });
  PopupActivity.setPopupClickedCallback(new PopupClickedInterface() {
   @Override
   public void popupClicked() {
    if (mCustomEventInterstitialListener != null)
     mCustomEventInterstitialListener.onAdClicked();
   }
  });
  PopupActivity.setPopupClosedCallback(new PopupClosedInterface() {   
   @Override
   public void popupClosed() {
    if (mCustomEventInterstitialListener != null)
     mCustomEventInterstitialListener.onAdClosed();
   }
  });

  Appnext.showPopupInActivity(mContext, mPlacementId, false);
 }
}

Tuesday, April 7, 2015

Detecting mobile app CPI frauds

Most CPI campaign work quite nicely. However, I saw this video which claim major click-frauds on Facebook ads from click-farms in specific countries. I've decided to re-check my last CPI campaign.

How I checked: by country, check the average session duration during the campaign. Filter only countries with average session duration less than 50% of the average.

Finding: At least 2 of the top 10 countries in the campaign clearly had a CPI fraud. The average session duration was less than 50% of the average, the CTR was x2-x4. Next time I'll look for it in real time. I've compared it with the data after the campaign & the session duration went back to normal.

Waste of money.

Bottom line: How I will search for ad frauds, at country level:
  1. Significantly low (or high) session duration
  2. Significantly high ad CTR rate

Sunday, January 11, 2015

Calculating Google Analytics event value variance & standard deviation

Here's I calculated the var & stddev of an event value (X) tracked by Google Analytics:
  1. Add a second event with the value X^2
  2. Calculate the variance using this formula: Var = E(X^2) - [E(X)]^2  (note that Google Analytics already calculates E(X^2) & E(X), which are, in this case the event's average).

Friday, November 28, 2014

Can Google Play Services introduce bugs to my apps without code update?

Here's a short list of FC bugs I think Google Play Services introduced remotely to my apps:

Wednesday, September 3, 2014

Removing app from Amazon App Store

Few years ago I had few apps published on Amazon App Store. Since the performance on that market wasn't impressive I didn't update them over time. Few weeks ago I decided to unpublish those apps.

Problem: No way to unpublish apps from the Amazon App Store.
Solution 1: Contact Amazon support and ask them to remove the app. They might want reasons and such.
Solution 2: Limit app distribution to the smallest market you can find on their list.