仿友盟统计安卓原生自定义的埋点统计功能的实现
一般的统计需求我们直接通过友盟统计或者talkingdata等第三方的SDK就能满足,但是如果统计的维度较多,参数需要自定义等情况,并且需要上传数据至自己公司后台的情况下,这时候就只能进行自定义了。

根据产品需求,服务端要求的数据样式为datas为业务字段,即为每次变化的字段,datas外为公共字段,如下:
数据格式
以下为自定义的埋点统计的工具类,核心代码如下:

package com.xx.xx.utils;

import android.content.Context;

import com.xx.xx.constants.JRWejoyConstants;
import com.xx.xx.xx.WeiboUtil;

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

/**
 * @ClassName: JRBorrowStatisticsUtil
 * @Description: 埋点统计工具类
 * @Author: yanxu5
 * @Date: 2019/3/27
 */
public class JRBorrowStatisticsUtil extends JRUtil {

    //业务字段埋点数据信息标识符(SP存储KEY值)
    private static final String JR_BORROW_STATISTICS = "jr_borrow_statistics";

    /**
     * -----------------------------------    缓存埋点数据相关(↓)    -------------------------------
     */

    //读取统计业务字段埋点数据
    public static JSONArray readBorrowStatistics(Context context) {
        String statisticsInfo = (String) JRSharedPreferencesUtil.getParam(context, JR_BORROW_STATISTICS, "");
        JSONArray jsonArray = null;
        try {
            jsonArray = new JSONArray(statisticsInfo);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return jsonArray;
    }

    //保存统计业务字段埋点数据
    private static void saveBorrowStatistics(Context context, JSONArray array) {
        JRSharedPreferencesUtil.setParam(context, JR_BORROW_STATISTICS, array.toString());
    }

    //清理统计业务字段埋点数据
    public static void clearBorrowStatistics(Context context) {
        JRSharedPreferencesUtil.remove(context, JR_BORROW_STATISTICS);
    }

    /**
     * -----------------------------------    具体相关业务方法(↓)    -------------------------------
     */

    //埋点的统计(供外界调用的方法)
    public static void eventDataCollect(Context context, String markName, String markType, String curPage, String refPage) {
        JSONArray array = JRBorrowStatisticsUtil.readBorrowStatistics(context);//读取埋点数据
        if (array == null) {
            array = new JSONArray();
        }
        JSONObject object = infoGenerated(context, markName, markType, curPage, refPage);//埋点
        array = InsertJSONObject(array, object);//插入新的埋点数据,重新赋值
        JRBorrowStatisticsUtil.saveBorrowStatistics(context, array);//保存埋点数据
    }

    //插入json数据
    private static JSONArray InsertJSONObject(JSONArray array, JSONObject object) {
        if (null != object) {
            return array.put(object);
        } else {
            return array;
        }
    }

    //业务字段埋点数据的产生
    private static JSONObject infoGenerated(Context context, String markName, String markType, String curPage, String refPage) {
        JSONObject object = null;
        try {
            object = new JSONObject();
            object.put("markName", markName);//事件名称--需传
            object.put("markType", markType);//行为类型--需传(pv/event)
            object.put("curPage", curPage);//当前页面--需传
            object.put("refPage", refPage);//来源页面--需传
            object.put("timestpEnter", JRDateUtil.formatDateAllType(System.currentTimeMillis()));//事件发生时间--本地
            object.put("lng", JRLocationUtil.getLongitude(context));//经度--本地
            object.put("lat", JRLocationUtil.getLatitude(context));//纬度--本地
            object.put("sessionid", JRBorrowSessionIdUtil.readBorrowSessionId(context));//会话id--本地
            object.put("netType", JRNetworkUtil.getNetworkType(context));//网络类型--本地
            object.put("wifiName", JRDeviceUtil.getConnectWifiName(context));//wifi名称--本地
            object.put("ipAddress", JRDeviceUtil.getIPAddress());//ip地址--本地
        } catch (Exception e) {
            e.printStackTrace();
        }
        return object;
    }

    //公共字段与业务字段进行拼接
    public static JSONObject initData(Context context, JSONArray jsonArray) {
        JSONObject object = null;
        try {
            object = new JSONObject();
            object.put("deviceId", WeiboUtil.getAid(context));//设备id--本地
            object.put("imei", JRDeviceUtil.getIMEI(context));//移动设备码--本地
            object.put("macAddress", JRDeviceUtil.getMacAddress(context));//Mac地址--本地
            object.put("model", JRDeviceUtil.getPhoneModel());//设备机型--本地
            object.put("osVersion", JRDeviceUtil.getSystemVersion());//平台版本号--本地
            object.put("os", "Android");//手机平台--本地
            object.put("appVersion", JRSystemUtil.getAppVersion(context));//app版本--本地
            object.put("userId", JRUserUtil.getWejoyUserId(context));//用户id--本地
            object.put("channel", "weibo");//渠道--本地
            object.put("firstChannel", JRWejoyConstants.FIRST_CHANNEL);//一级渠道--本地
            object.put("subChannel", JRWejoyConstants.SUB_CHANNEL);//子渠道--本地
            object.put("brand", JRWejoyConstants.BRAND);//产品品牌--本地
            object.put("datas", jsonArray);//业务字段
        } catch (Exception e) {
            e.printStackTrace();
        }
        return object;
    }

}

在需要统计埋点的地方通过如下方式调用:

JRBorrowStatisticsUtil.eventDataCollect(v.getContext(), JREvent.BORROW_MINE_CARD_CLICK, "event", "BankCardEntranceActivity", "UserFragment");

在需要调用接口上传的地方通过如下代码调用:

/**
     * 上传埋点信息(满十条上传一次)
     */
    private void pushBorrowStatisticsData() {
        final JSONArray jsonArray = JRBorrowStatisticsUtil.readBorrowStatistics(this);
        if (jsonArray == null || jsonArray.length() < 10) {
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                String data = JRBorrowStatisticsUtil.initData(MainActivity.this, jsonArray).toString();
                JRBorrowExtraApi.borrowStatisticsUpload(MainActivity.this, TAG, data);
            }
        }).start();
    }

注:这里的策略是在每次打开app的时候进行数据上传,为了不影响业务逻辑,所以在子线程中上传,同时为了减少接口的调用压力,只有当数据大于10条才进行上传,当然你也可以在工具类内部进行判断,这里根据具体需求进行调整

最后在上传成功后别忘记调用clearBorrowStatistics(Context context)清空数据,避免产生垃圾数据。

//上传成功后删除缓存数据
JRBorrowStatisticsUtil.clearBorrowStatistics(context);

以上就是自定义埋点统计的全部代码,核心逻辑就是先缓存到本地,同时数据是以json的形式插入,过程灵活方便,方便调整。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐