cn.sharesdk.analysis.EventManager.java Source code

Java tutorial

Introduction

Here is the source code for cn.sharesdk.analysis.EventManager.java

Source

/**
 * ************************************************************
 * ShareSDKStatistics
 * An open source analytics android sdk for mobile applications
 * ************************************************************
 * 
 * @package      ShareSDK Statistics
 * @author      ShareSDK Limited Liability Company
 * @copyright   Copyright 2014-2016, ShareSDK Limited Liability Company
 * @since      Version 1.0
 * @filesource  https://github.com/OSShareSDK/OpenStatistics/tree/master/Android
 *  
 * *****************************************************
 * This project is available under the following license
 * *****************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package cn.sharesdk.analysis;

import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.TextUtils;
import cn.sharesdk.analysis.db.MessageUtils;
import cn.sharesdk.analysis.model.AIDLCacheEvent;
import cn.sharesdk.analysis.model.EventType;
import cn.sharesdk.analysis.model.PostEvent;
import cn.sharesdk.analysis.server.RemoteService;
import cn.sharesdk.analysis.util.CrashHandler;
import cn.sharesdk.analysis.util.DeviceHelper;
import cn.sharesdk.analysis.util.Ln;
import cn.sharesdk.analysis.util.PreferencesHelper;
import cn.sharesdk.analysis.server.AIDLService;

public class EventManager {

    private static Context context;
    private static String start_date = null;// The start time point
    private static long start = 0;
    private static String end_date = null;// The end time point
    private static long end = 0;//
    private static String duration = null;// run time

    private static String session_id = null;
    private static String last_activity = "APP_START";// currnet activity's name
    private static String current_activity = null;// currnet activity's name
    private static String appkey = "";

    // session continue millis
    private static long sessionContinueMillis = 30000L;

    private static boolean activityTrack = true;

    private static PreferencesHelper dbHelper;
    private static DeviceHelper deviceHelper;
    //
    private static HashMap<String, Long> eventDurationMap = new HashMap<String, Long>();
    //?label?
    private static HashMap<String, String> eventLabelMap = new HashMap<String, String>();
    //?
    private static HashMap<String, Long> pageDurationMap = new HashMap<String, Long>();
    //?
    //
    private static ArrayList<AIDLCacheEvent> settingEventList = new ArrayList<AIDLCacheEvent>();
    private static ArrayList<AIDLCacheEvent> cacheEventList = new ArrayList<AIDLCacheEvent>();

    private static AIDLService aidlService;

    public static synchronized void init(Context c) {
        if (context == null && c != null) {
            context = c.getApplicationContext();
            dbHelper = PreferencesHelper.getInstance(context);
            deviceHelper = DeviceHelper.getInstance(context);
            isServiceConnect(context);

        } else if (context == null && c == null) {
            Ln.e("Context is null", "call setContext to set it");
        }
    }

    private static ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            aidlService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            aidlService = AIDLService.Stub.asInterface(service);
            //TOTO setting base params after server connect
            try {

                for (AIDLCacheEvent cacheEvent : settingEventList) {
                    //the setting must be done at first
                    if (EventType.SETTING == cacheEvent.eventType) {
                        aidlService.setting(cacheEvent.key, cacheEvent.value);
                    }
                }

                for (AIDLCacheEvent cacheEvent : cacheEventList) {
                    if (EventType.SAVELOG == cacheEvent.eventType) {
                        aidlService.saveLog(cacheEvent.key, cacheEvent.value);
                    } else if (EventType.UPLOAD_LOG == cacheEvent.eventType) {
                        aidlService.uploadLog();
                    }
                }
                settingEventList.clear();
                cacheEventList.clear();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    public static void openActivityDurationTrack(boolean activityTrack) {
        EventManager.activityTrack = activityTrack;
    }

    public static void setBaseURL(String url) {
        if (!TextUtils.isEmpty(url)) {
            startSettingService(RemoteService.SET_PREURL, url);
        }
    }

    public static void setAppKey(String appkey) {
        if (!TextUtils.isEmpty(appkey)) {
            EventManager.appkey = appkey;
            startSettingService(RemoteService.SET_APP_KEY, appkey);
        }
    }

    public static void setDebugMode(boolean isdebug) {
        Ln.DebugMode = isdebug;
        startSettingService(RemoteService.SET_ISDEBUG, String.valueOf(isdebug));
    }

    public static String getAppKey() {
        if (TextUtils.isEmpty(appkey)) {
            appkey = deviceHelper.getAppKey();
        }
        return appkey;
    }

    public static void setChannel(String channel) {
        if (!TextUtils.isEmpty(channel)) {
            startSettingService(RemoteService.SET_CHANNEL, channel);
        }
    }

    public static void setSessionContinueMillis(long interval) {
        sessionContinueMillis = interval;
    }

    /** post errors' log */
    public static void onError(Context context, String error) {
        init(context);
        startLogService(MessageUtils.ERROR_DATA, getErrorJSONObject(error));
    }

    /** set error listener */
    public static void onError(Context context) {
        init(context);
        CrashHandler handler = CrashHandler.getInstance();
        handler.init(context);
        Thread.setDefaultUncaughtExceptionHandler(handler);
    }

    public static void onEventBegin(Context context, String event_id) {
        init(context);
        eventDurationMap.put(event_id, System.currentTimeMillis());
    }

    public static void onEventBegin(Context context, String event_id, String label) {
        init(context);
        eventLabelMap.put(event_id, label);
        eventDurationMap.put(event_id, System.currentTimeMillis());
    }

    public static long onEventEnd(Context context, String event_id) {
        init(context);
        if (eventDurationMap.containsKey(event_id)) {
            long start = eventDurationMap.remove(event_id);
            long duration = System.currentTimeMillis() - start;
            return duration;
        } else {
            Ln.e("error : onEventEnd ===>>> ", "do not call onEventBegin, duration is 0");
            return 0;
        }

    }

    public static long onEventEnd(Context context, String event_id, String label) {
        init(context);
        if (eventDurationMap.containsKey(event_id) && eventLabelMap.containsKey(event_id)) {
            String mLabel = eventLabelMap.remove(event_id);
            if (!mLabel.equals(label)) {
                Ln.e("error : onEventEnd ===>>> ", "the param of label is not equal");
                return 0;
            }
            long start = eventDurationMap.remove(event_id);
            long duration = System.currentTimeMillis() - start;
            return duration;
        } else {
            Ln.e("error : onEventEnd ===>>> ", "do not call onEventBegin or label is not equal");
            return 0;
        }

    }

    public static void setAutoLocation(boolean isLocation) {
        startSettingService(RemoteService.SET_LOCATION, String.valueOf(isLocation));
    }

    public static void onPageStart(String pageName) {
        if (context == null) {
            Ln.e("Context is null", "call onResume() to initsdk");
            return;
        }
        //TODO umeng ???activityTrack,?
        current_activity = pageName;
        pageDurationMap.put(pageName, System.currentTimeMillis());
        if (context != null) {
            onResume(context, null, null);
        }
    }

    public static void onPageEnd(String pageName) {
        if (context == null) {
            Ln.e("Context is null", "call onResume() to initsdk");
            return;
        }
        //TODO umeng ???activityTrack,?
        long pageStart = pageDurationMap.remove(pageName);
        if (pageStart == 0) {
            Ln.e("error : onPageEnd ===>>> ", "do not call onPageStart or the param of pageName is not equal");
            return;
        } else {
            if (context != null) {
                onPause(context);
                current_activity = null;
            }
        }

    }

    private static void isCreateNewSessionID() {
        try {
            if (session_id == null) {
                generateSeesion();
                return;
            }

            long currenttime = System.currentTimeMillis();
            long session_save_time = dbHelper.getSessionTime();

            if (currenttime - session_save_time > sessionContinueMillis) {
                generateSeesion();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * create sessionID
     */
    private static String generateSeesion() {
        dbHelper.setAppStartDate();
        String sessionId = "";
        String str = getAppKey();
        if (str != null) {
            str = str + deviceHelper.getTime() + deviceHelper.getDeviceID();
            sessionId = deviceHelper.md5(str);
            dbHelper.setSessionTime();
            dbHelper.setSessionID(sessionId);
            session_id = sessionId;
            Ln.i("MobclickAgent: ", "Start new session :" + session_id);

            // post device and launch data
            startLogService(MessageUtils.LAUNCH_DATA, getLaunchJSONObject());

            return sessionId;
        } else {
            Ln.e("MobclickAgent", "protocol Header need Appkey or Device ID ,Please check AndroidManifest.xml ");
        }
        return sessionId;
    }

    /**
     * post app's pause log
     */
    public static void onPause(Context context) {
        init(context);
        //TODO umeng activity??activityTrack
        dbHelper.setSessionTime();

        end_date = deviceHelper.getTime();
        end = Long.valueOf(System.currentTimeMillis());
        duration = end - start + "";

        if (!TextUtils.isEmpty(current_activity)) {
            startLogService(MessageUtils.PAGE_DATA, getPauseJSONObject());
        }
    }

    /**
     * post app's resume log
     */
    public static void onResume(Context context, String appkey, String channel) {
        init(context);
        if (!TextUtils.isEmpty(appkey)) {
            setAppKey(appkey);
        }
        if (!TextUtils.isEmpty(channel)) {
            setChannel(channel);
        }

        isCreateNewSessionID();
        if (activityTrack)
            current_activity = deviceHelper.getActivityName();

        start_date = deviceHelper.getTime();
        start = Long.valueOf(System.currentTimeMillis());

    }

    /** post launch data to server */
    public static void postLaunchDatas(Context context) {
        init(context);
        startLogService(MessageUtils.LAUNCH_DATA, getLaunchJSONObject());
    }

    /** post event info */
    public static void onEvent(Context context, PostEvent event) {
        init(context);
        //TODO 
        //      if (!event.verification()) {
        //         Log.w("MobclickAgent", "Illegal value of acc in postEventInfo");
        //         return;
        //      }
        if (event.getStringMap() != null) {
            startLogService(MessageUtils.HASH_EVENT_DATA, event.eventToJOSNObj());
        } else {
            startLogService(MessageUtils.EVENT_DATA, event.eventToJOSNObj());
        }

    }

    /** post event info */
    public static void onEventDuration(Context context, PostEvent event) {
        init(context);
        if (event.getDuration() == 0) {
            Ln.e("onEventDuration", "onEventDuration the duration is 0");
            return;
        }
        if (event.getStringMap() != null) {
            startLogService(MessageUtils.HASH_EVENT_DATA, event.eventToJOSNObj());
        } else {
            startLogService(MessageUtils.EVENT_DATA, event.eventToJOSNObj());
        }

    }

    private static void isServiceConnect(Context context) {
        Ln.e("isServiceConnect ==>>", "bindService");
        if (context != null) {
            Intent service = new Intent(context, RemoteService.class);
            service.setAction("cn.sharesdk.analysis.server.AIDLService");
            context.startService(service);
            context.bindService(service, connection, Context.BIND_AUTO_CREATE);
        }
    }

    /** upload all log */
    public static void uploadLog(Context context) {
        init(context);
        try {
            if (aidlService != null) {
                aidlService.uploadLog();
            } else {
                cacheEventList.add(new AIDLCacheEvent(EventType.UPLOAD_LOG));
                isServiceConnect(context);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**Save and send log to server on the service*/
    public static void startLogService(String action, JSONObject jsonObject) {
        try {
            if (jsonObject == null) {
                return;
            }
            String json = jsonObject.toString();
            if (TextUtils.isEmpty(json)) {
                return;
            }
            if (aidlService != null) {
                aidlService.saveLog(action, json);
            } else {
                cacheEventList.add(new AIDLCacheEvent(EventType.SAVELOG, action, json));
                isServiceConnect(context);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**Save and send log to server on the service*/
    private static void startSettingService(String action, String extraValue) {
        try {
            if (aidlService != null) {
                aidlService.setting(action, extraValue);
            } else {
                settingEventList.add(new AIDLCacheEvent(EventType.SETTING, action, extraValue));
                isServiceConnect(context);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /** get json of launch msg */
    private static JSONObject getLaunchJSONObject() {
        JSONObject launchData = new JSONObject();
        try {
            launchData.put("create_date", dbHelper.getAppStartDate());
            launchData.put("last_end_date", dbHelper.getAppExitDate());
            launchData.put("session_id", session_id);

            //Ln.i("launchData---------->", launchData.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return launchData;
    }

    /** get json of error msg */
    private static JSONObject getErrorJSONObject(String error) {
        if (TextUtils.isEmpty(error)) {
            return null;
        }
        JSONObject errorData = new JSONObject();
        try {
            String headstring = error;
            if (error.contains("Caused by:")) {
                String ssString = error.substring(error.indexOf("Caused by:"));
                String[] ss = ssString.split("\n\t");
                if (ss.length >= 1)
                    headstring = ss[0];
            }

            errorData.put("session_id", session_id);
            errorData.put("create_date", deviceHelper.getTime());
            errorData.put("page", deviceHelper.getActivityName());
            errorData.put("error_log", headstring);
            errorData.put("stack_trace", error);

            //Ln.i("errorData---------->", errorData.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return errorData;
    }

    /** get json of activity onPause msg */
    private static JSONObject getPauseJSONObject() {
        JSONObject pauseData = new JSONObject();
        try {
            pauseData.put("session_id", session_id);
            pauseData.put("start_date", start_date);
            pauseData.put("end_date", end_date);
            pauseData.put("page", current_activity);
            pauseData.put("from_page", last_activity);
            pauseData.put("duration", duration);
            //save the last activity name
            last_activity = current_activity;
            //Ln.i("pauseData---------->", pauseData.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return pauseData;
    }

}