package kidozen.client.analytics; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.util.Log; import com.google.gson.Gson; import org.apache.http.HttpStatus; import org.json.JSONObject; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.concurrent.TimeUnit; import kidozen.client.AnalyticsLog; import kidozen.client.ServiceEvent; import kidozen.client.ServiceEventListener; import kidozen.client.analytics.events.ActivityEvent; import kidozen.client.analytics.events.ClickEvent; import kidozen.client.analytics.events.CustomEvent; import kidozen.client.analytics.events.SessionStartEvent; import kidozen.client.authentication.KidoZenUser; /** * Created by christian on 10/22/14. */ public class Analytics { final String TAG = this.getClass().getSimpleName(); static Analytics mSingleton = null; private Session mSession = null; private Context mContext = null; private Uploader mUploader = null; private AnalyticsLog mLogger; private KidoZenUser mUserIdentity; private String appVersion; public void setmUserIdentity(KidoZenUser mUserIdentity) { this.mUserIdentity = mUserIdentity; } public static Analytics getInstance() { if (mSingleton == null) { mSingleton = new Analytics(); } return mSingleton; } public static Analytics getInstance(Boolean enable, Context context, AnalyticsLog logger, KidoZenUser user) { if (mSingleton == null) { mSingleton = new Analytics(); mSingleton.setmUserIdentity(user); mSingleton.Enable(enable,context,logger); } return mSingleton; } public void Enable(Boolean enable, Context context, AnalyticsLog logger) { if (enable) { mContext = (!context.getClass().isInstance(android.app.Application.class) ? context.getApplicationContext() : context); appVersion = getAppVersion(mContext); mLogger = logger; mSession = new Session(context); checkPendingSessions(); mSession.StartNew(mUserIdentity.getUserHash()); mUploader = Uploader.getInstance(mContext, mSession, mLogger); mUploader.StartUploaderTransitionTimer(); mSession.sessionStart(new SessionStartEvent(mContext, mSession.getUUID(), mUserIdentity.getUserHash(), appVersion)); } else { mSession = null; } } private String getAppVersion(Context context) { try { PackageInfo packageInfo = context.getPackageManager() .getPackageInfo(context.getPackageName(), 0); return new Integer(packageInfo.versionCode).toString(); } catch (PackageManager.NameNotFoundException e) { // should never happen throw new RuntimeException("Could not get package name: " + e); } } //In android we don't have a reliable method to check if the whole application was closed by user or OS //Maybe a previous application was closed and pending events must be sent private void checkPendingSessions() { try { ArrayList<String> sessions = mSession.GetPendingSessions(); for (final String s : sessions) { String sessionDetails = mSession.readFile(s); Gson gson = new Gson(); SessionDetails details = gson.fromJson(sessionDetails,SessionDetails.class); details.EndDate = new Date().getTime(); details.length = details.EndDate - details.StartDate; details.eventAttr.sessionLength = TimeUnit.MILLISECONDS.toSeconds(details.length) % 60; details.isPeding = true; //serialize again to upload to server sessionDetails = gson.toJson(details); String pendingSessionAndEvents = "[" + sessionDetails + "]"; final String eventsFileName = s.replace(".session",".events"); final String events = mSession.readFile(eventsFileName); // If there was events, adds the session details to events array if ( events!=null && !events.isEmpty()) { int endJsonArray = events.lastIndexOf("]"); if (endJsonArray>0) { String message = events.substring(0,endJsonArray); pendingSessionAndEvents = message + "," + sessionDetails + "]"; } } Log.d(TAG, "Uploading pending session & events"); mLogger.Write(pendingSessionAndEvents, new ServiceEventListener() { @Override public void onFinish(ServiceEvent e) { if (e.StatusCode == HttpStatus.SC_CREATED) { if ( events!=null && !events.isEmpty()) mContext.deleteFile(eventsFileName); mContext.deleteFile(s); Log.d(TAG, "Uploaded pending session & events"); } } }); } } catch (IOException e) { e.printStackTrace(); } } public void StartSession() { mSession.ResetEvents(); mUploader = Uploader.getInstance(mContext, mSession, mLogger); mUploader.StartUploaderTransitionTimer(); mSession.sessionStart(new SessionStartEvent(mContext, mSession.getUUID(), mUserIdentity.getUserHash(), appVersion)); } public void StopSession() { new Thread() { @Override public void run() { mUploader.StopUploaderTransmissionTimer(); mUploader.UploadSession(); mUploader.StartUploaderTransitionTimer(); } }.start(); } public void TagClick(String data) { ClickEvent event = new ClickEvent(data, mSession.getUUID(), mUserIdentity.getUserHash(), appVersion); mSession.LogEvent(event); } public void TagActivity(String data) { ActivityEvent event = new ActivityEvent(data, mSession.getUUID(), mUserIdentity.getUserHash(), appVersion); mSession.LogEvent(event); } public void TagEvent(String title, JSONObject data) { CustomEvent event = new CustomEvent(title,data, mSession.getUUID(), mUserIdentity.getUserHash(), appVersion); mSession.LogEvent(event); } public void SetSessionTimeOutInSeconds(int timeout) { mSession.setSessionTimeoutInSeconds(timeout); mUploader.StartUploaderTransitionTimer(); } }