看一下我们自定义的WrapperOnClickListener
/*public*/ class WrapperOnClickListener implements android.view.View.OnClickListener { private android.view.View.OnClickListener source; WrapperOnClickListener(android.view.View.OnClickListener source) { this.source = source; } @Override public void onClick(android.view.View view) { //调用原有的 OnClickListener try { if (source != null) { source.onClick(view); } } catch (Exception e) { e.printStackTrace(); } //插入埋点代码 SensorsDataPrivate.trackViewOnClick(view); } }
很简单,也是实现系统的OnClickListener
方法,然后在执行click的时候插入埋点代码
。
然后看一下trackViewOnClick
方法:
public static void trackViewOnClick(android.view.View view) { try { JSONObject jsonObject = new JSONObject(); jsonObject.put("element_type", view.getClass().getCanonicalName()); jsonObject.put("element_id", getViewId(view)); jsonObject.put("element_content", getElementContent(view)); Activity activity = getActivityFromView(view); if (activity != null) { jsonObject.put("activity", activity.getClass().getCanonicalName()); } SensorsDataAPI.getInstance().trackClick("$AppClick", jsonObject); } catch (Exception e) { e.printStackTrace(); } }
比较简单,但是有两个参数是需要注意的:
element_type
控件的类型,比如TextView、Buttonelement_id
控件的id,页面全路径 + 控件id即可表示唯一标示了
然后就是trackClick
方法了
public void trackClick(@androidx.annotation.NonNull String eventName, @androidx.annotation.Nullable JSONObject properties) { try { JSONObject jsonObject = new JSONObject(); jsonObject.put("event", eventName); // jsonObject.put("device_id", mDeviceId); JSONObject sendProperties = new JSONObject(mDeviceInfo); String act = properties.get("activity").toString(); //获取页面的参数 if (act.contains("SecondActivity")) { SecondActivity activity = (SecondActivity) SensorsDataPrivate.getCurrentActivity(); String userId = activity.getIntent().getStringExtra("userId"); properties.put("userId", userId); } if (properties != null) { SensorsDataPrivate.mergeJSONObject(properties, sendProperties); } jsonObject.put("extras", sendProperties); jsonObject.put("eventTime", System.currentTimeMillis()); jsonObject.put("sessionId", UUID.randomUUID().toString().replace("-", "")); Log.i(TAG, SensorsDataPrivate.formatJson(jsonObject.toString())); } catch (Exception e) { e.printStackTrace(); } }
跟页面的埋点基本差不太多,来看看数据:
{ "event": "$AppClick", "extras": { "app_name": "TrackDemo", "screen_width": 1440, "screen_height": 2621, "app_version": "1.0", "os_version": "10", "model": "Android SDK built for x86", "manufacturer": "Google", "element_type": "androidx.appcompat.widget.AppCompatButton", "element_id": "button", "element_content": "点击传值跳转", "activity": "com.yechaoa.trackdemo.ui.MainActivity" }, "eventTime": 1603279293756, "sessionId": "b8d1aa32039a4fb1b2ece7772d60cd0e" }
可以看到数据都是正常的,但是element_content字段并不能太过依赖,为什么呢,因为这个是获取的控件文本,不是所有的控件都有文本的,比如没有描述的ImageView、CheckBox等。
这些都是系统的控件,那如果是我们自定义View怎么办呢,正好演示一下事件的手动埋点。
button2.setOnClickListener { val jsonObject = JSONObject() jsonObject.put("element_type", "androidx.constraintlayout.widget.ConstraintLayout") jsonObject.put("element_id", "自定义id") jsonObject.put("element_content", "自定义内容") jsonObject.put("id", 1234) jsonObject.put("activity", this.javaClass.canonicalName) SensorsDataAPI.getInstance().trackClick("AppClick", jsonObject) }
看一下数据:
{ "event":"AppClick", "extras":{ "app_name":"TrackDemo", "screen_width":1440, "screen_height":2621, "app_version":"1.0", "os_version":"10", "model":"Android SDK built for x86", "manufacturer":"Google", "element_type":"androidx.constraintlayout.widget.ConstraintLayout", "element_id":"自定义id", "element_content":"自定义内容", "id":1234, "activity":"com.yechaoa.trackdemo.ui.SecondActivity", "userId":"111" }, "eventTime":1603283095128, "sessionId":"addbc3d8335244328fcd352221a7a11d" }
加入自定义view监测不到的情况下,就可以用这种方式来手动埋点。
除了正常的单个控件的点击事件之外,还有列表的item click事件、还有RatingBar等等,限于篇幅就不细说了,原理都是相通的,具体可以查看Demo。
Demo:https://github.com/yechaoa/TrackDemo