99
1010import java .io .IOException ;
1111import java .lang .reflect .Type ;
12+ import java .util .Date ;
1213import java .util .HashMap ;
1314
1415import okhttp3 .Call ;
@@ -26,6 +27,8 @@ public final class Metricalp {
2627
2728 public final String API_ENDPOINT = "https://event.metricalp.com" ;
2829 private HashMap <String , String > attributes = null ;
30+ private String currentScreen = null ;
31+ private long screenDurationStartPoint = new Date ().getTime ();
2932
3033 public OkHttpClient client = new OkHttpClient ();
3134
@@ -40,7 +43,7 @@ public static Metricalp getInstance() {
4043 return INSTANCE ;
4144 }
4245
43- public static boolean init (HashMap <String , String > attributes , String initialScreen ) {
46+ public static boolean init (HashMap <String , String > attributes , String initialScreen , HashMap < String , String > eventAttributes ) {
4447 Metricalp instance = Metricalp .getInstance ();
4548 if (instance .getAttributes () == null ) {
4649 attributes .put ("metr_collected_via" , "android" );
@@ -52,7 +55,7 @@ public static boolean init(HashMap<String, String> attributes, String initialScr
5255 return true ;
5356 }
5457
55- return Metricalp .screenViewEvent (initialScreen , null , null );
58+ return Metricalp .screenViewEvent (initialScreen , eventAttributes , null );
5659 }
5760
5861 public HashMap <String , String > getAttributes () {
@@ -63,6 +66,21 @@ public void setAttributes(HashMap<String, String> attributes) {
6366 this .attributes = attributes ;
6467 }
6568
69+ public String getCurrentScreen () {
70+ return currentScreen ;
71+ }
72+
73+ public void setCurrentScreen (String currentScreen ) {
74+ this .currentScreen = currentScreen ;
75+ }
76+
77+ public long getScreenDurationStartPoint () {
78+ return screenDurationStartPoint ;
79+ }
80+
81+ public void setScreenDurationStartPoint (long screenDurationStartPoint ) {
82+ this .screenDurationStartPoint = screenDurationStartPoint ;
83+ }
6684
6785 public static void resetAttributes (HashMap <String , String > attributes ) {
6886 Metricalp instance = Metricalp .getInstance ();
@@ -81,42 +99,42 @@ public static HashMap<String, String> getAllAttributes() {
8199 return instance .getAttributes ();
82100 }
83101
84- public static boolean sendEvent (String type , HashMap <String , String > eventAttributes , HashMap <String , String > overrideAttributes ) {
102+ public static boolean sendEvent (String type , HashMap <String , String > eventAttributes , HashMap <String , String > overrideConfigurationAttributes ) {
85103 Metricalp instance = Metricalp .getInstance ();
86104 HashMap <String , String > attributes = instance .getAttributes ();
87105 HashMap <String , String > body = new HashMap <>(attributes );
88106
89107 body .putAll (attributes );
90108
91- if (overrideAttributes != null ) {
92- body .putAll (overrideAttributes );
109+ if (overrideConfigurationAttributes != null ) {
110+ body .putAll (overrideConfigurationAttributes );
93111 }
94112
95113 if (!body .containsKey ("tid" )) {
96114 throw new RuntimeException ("Metricalp: tid is missing in attributes" );
97115 }
98116
99- if (body . containsKey ( "metr_bypass_ip" ) && !body .containsKey ("metr_unique_identifier" )) {
100- throw new RuntimeException ("Metricalp: when metr_bypass_ip is true, metr_unique_identifier must be set." );
117+ if (!body .containsKey ("metr_unique_identifier" )) {
118+ throw new RuntimeException ("Metricalp: metr_unique_identifier must be set." );
101119 }
102120
103-
104121 if (eventAttributes != null ) {
105122 body .putAll (eventAttributes );
106- body .put ("path" , eventAttributes .getOrDefault ("path" , "(not-set)" ));
107123 }
108124
109125 body .put ("type" , type );
110126
111-
112127 if (!body .containsKey ("metr_user_language" )) {
113128 body .put ("metr_user_language" , "unknown-unknown" );
114129 }
115130
116- if (!body .containsKey ("metr_unique_identifier " )) {
117- body .put ("metr_unique_identifier " , "" );
131+ if (!body .containsKey ("path " )) {
132+ body .put ("path " , "(not-set) " );
118133 }
119134
135+ if (!body .containsKey ("metr_bypass_ip" )) {
136+ body .put ("metr_bypass_ip" , "true" );
137+ }
120138
121139 String apiUrl = attributes .getOrDefault ("endpoint" , instance .API_ENDPOINT );
122140 Gson gson = new Gson ();
@@ -129,37 +147,87 @@ public static boolean sendEvent(String type, HashMap<String, String> eventAttrib
129147 return true ;
130148 }
131149
132- public static boolean screenViewEvent (String path , HashMap <String , String > eventAttributes , HashMap <String , String > overrideAttributes ) {
150+ public static boolean screenViewEvent (String path , HashMap <String , String > eventAttributes , HashMap <String , String > overrideConfigurationAttributes ) {
133151 HashMap <String , String > attrs = new HashMap <>();
134- attrs .put ("path" , path );
152+ Metricalp instance = Metricalp .getInstance ();
153+ String prevScreen = instance .getCurrentScreen ();
154+
155+ if (path != null ) {
156+ attrs .put ("path" , path );
157+ }
158+
159+ HashMap <String , String > screenLeaveAttrs = new HashMap <>();
160+
161+ if (prevScreen != null ) {
162+ screenLeaveAttrs .put ("leave_from_path" , prevScreen );
163+ screenLeaveAttrs .put ("leave_from_duration" , String .valueOf (new Date ().getTime () - instance .getScreenDurationStartPoint ()));
164+ }
165+
166+ instance .setCurrentScreen (null );
167+ instance .setScreenDurationStartPoint (new Date ().getTime ());
168+
169+ attrs .putAll (screenLeaveAttrs );
170+
135171 if (eventAttributes != null ) {
136172 attrs .putAll (eventAttributes );
137173 }
174+
138175 return Metricalp .sendEvent (
139176 "screen_view" ,
140177 attrs ,
141- overrideAttributes
178+ overrideConfigurationAttributes
179+ );
180+ }
181+
182+ public static boolean appLeaveEvent ( HashMap <String , String > eventAttributes , HashMap <String , String > overrideConfigurationAttributes ) {
183+ HashMap <String , String > attrs = new HashMap <>();
184+ Metricalp instance = Metricalp .getInstance ();
185+ String prevPath = instance .getCurrentScreen ();
186+
187+ if (prevPath == null ) {
188+ return false ;
189+ }
190+
191+ long screenDuration = new Date ().getTime () - instance .getScreenDurationStartPoint ();
192+ instance .setScreenDurationStartPoint (new Date ().getTime ());
193+ instance .setCurrentScreen (null );
194+
195+ attrs .put ("path" , prevPath );
196+ attrs .put ("screen_duration" , String .valueOf (screenDuration ));
197+
198+ if (eventAttributes != null ) {
199+ attrs .putAll (eventAttributes );
200+ }
201+
202+ return Metricalp .sendEvent (
203+ "screen_leave" ,
204+ attrs ,
205+ overrideConfigurationAttributes
142206 );
143207 }
144208
145- public static boolean sessionExitEvent (String path , HashMap <String , String > eventAttributes , HashMap <String , String > overrideAttributes ) {
209+
210+ // @deprecated No more manual session exit event
211+ public static boolean sessionExitEvent (String path , HashMap <String , String > eventAttributes , HashMap <String , String > overrideConfigurationAttributes ) {
146212 HashMap <String , String > attrs = new HashMap <>();
147- attrs .put ("path" , path );
213+ if (path != null ) {
214+ attrs .put ("path" , path );
215+ }
148216 if (eventAttributes != null ) {
149217 attrs .putAll (eventAttributes );
150218 }
151219 return Metricalp .sendEvent (
152220 "session_exit" ,
153221 attrs ,
154- overrideAttributes
222+ overrideConfigurationAttributes
155223 );
156224 }
157225
158- public static boolean customEvent (String type , HashMap <String , String > eventAttributes , HashMap <String , String > overrideAttributes ) {
226+ public static boolean customEvent (String type , HashMap <String , String > eventAttributes , HashMap <String , String > overrideConfigurationAttributes ) {
159227 return Metricalp .sendEvent (
160228 type ,
161229 eventAttributes ,
162- overrideAttributes
230+ overrideConfigurationAttributes
163231 );
164232 }
165233
0 commit comments