Sfoglia il codice sorgente

Add flurry analytics

Various changes to activity recorder algorithm
tags/ActivityRecorder/0.2.0
Chris Smith 14 anni fa
parent
commit
9f8b155648
22 ha cambiato i file con 277 aggiunte e 31 eliminazioni
  1. 1
    1
      code/ActivityRecorder/AndroidManifest.xml
  2. 4
    0
      code/ActivityRecorder/build.xml
  3. BIN
      code/ActivityRecorder/dist/ActivityRecorder.apk
  4. BIN
      code/ActivityRecorder/lib/FlurryAgent.jar
  5. 3
    1
      code/ActivityRecorder/nbproject/project.properties
  6. 3
    0
      code/ActivityRecorder/res/values/strings.xml
  7. 19
    0
      code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/ActivityRecorderActivity.java
  8. 2
    2
      code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/ClassifierService.java
  9. 10
    7
      code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/R.java
  10. 116
    15
      code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/RecorderService.java
  11. 4
    3
      code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/rpc/Classification.java
  12. 1
    1
      code/SensorLogger/AndroidManifest.xml
  13. 3
    0
      code/SensorLogger/build.xml
  14. BIN
      code/SensorLogger/dist/SensorLogger.apk
  15. BIN
      code/SensorLogger/lib/FlurryAgent.jar
  16. 3
    1
      code/SensorLogger/nbproject/project.properties
  17. 18
    0
      code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/CountdownActivity.java
  18. 19
    0
      code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/IntroActivity.java
  19. 18
    0
      code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/RecordingActivity.java
  20. 25
    0
      code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/ResultsActivity.java
  21. 17
    0
      code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/ThanksActivity.java
  22. 11
    0
      website/index.html

+ 1
- 1
code/ActivityRecorder/AndroidManifest.xml Vedi File

@@ -1,6 +1,6 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2 2
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
-     package="uk.co.md87.android.activityrecorder" android:versionCode="2" android:versionName="0.1.3">
3
+     package="uk.co.md87.android.activityrecorder" android:versionCode="4" android:versionName="0.2.1">
4 4
     <application android:label="Activity Recorder" android:icon="@drawable/icon">
5 5
          <activity android:name=".ActivityRecorderActivity" android:label="Activity Recorder">
6 6
             <intent-filter>

+ 4
- 0
code/ActivityRecorder/build.xml Vedi File

@@ -18,4 +18,8 @@
18 18
 
19 19
     <target depends="init,compile,-pre-jar,-dex,-package-res-and-assets,-package-res-no-assets,-package-dex,-build-without-signing,-post-jar" description="Build unsigned JAR." name="unsigned-jar"/>
20 20
 
21
+    <target name="-pre-jar">
22
+       <unzip src="lib/FlurryAgent.jar" dest="${build.classes.dir}" overwrite="true"/>
23
+    </target>
24
+
21 25
 </project>

BIN
code/ActivityRecorder/dist/ActivityRecorder.apk Vedi File


BIN
code/ActivityRecorder/lib/FlurryAgent.jar Vedi File


+ 3
- 1
code/ActivityRecorder/nbproject/project.properties Vedi File

@@ -17,10 +17,12 @@ dist.apk=${dist.dir}/ActivityRecorder.apk
17 17
 dist.dir=dist
18 18
 dist.javadoc.dir=${dist.dir}/javadoc
19 19
 excludes=
20
+file.reference.FlurryAgent.jar=lib/FlurryAgent.jar
20 21
 gen.source.dir=${src.dir}
21 22
 includes=**
22 23
 intermediate.dex=${build.dir}/classes.dex
23
-javac.classpath=
24
+javac.classpath=\
25
+    ${file.reference.FlurryAgent.jar}
24 26
 # Space-separated list of extra javac options
25 27
 javac.compilerargs=
26 28
 javac.deprecation=false

+ 3
- 0
code/ActivityRecorder/res/values/strings.xml Vedi File

@@ -9,11 +9,14 @@
9 9
 
10 10
     <string name="activity_unknown">Unknown</string>
11 11
     <string name="activity_walking">Walking</string>
12
+    <string name="activity_walking_stairs">Walking (stairs)</string>
12 13
     <string name="activity_walking_stairs_up">Walking (up stairs)</string>
13 14
     <string name="activity_walking_stairs_down">Walking (down stairs)</string>
14 15
     <string name="activity_dancing">Dancing</string>
16
+    <string name="activity_idle">Idle</string>
15 17
     <string name="activity_idle_standing">Standing still</string>
16 18
     <string name="activity_idle_sitting">Sitting down</string>
19
+    <string name="activity_vehicle">Travelling</string>
17 20
     <string name="activity_vehicle_bus">Travelling by bus</string>
18 21
     <string name="activity_vehicle_car">Travelling by car</string>
19 22
 </resources>

+ 19
- 0
code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/ActivityRecorderActivity.java Vedi File

@@ -22,6 +22,7 @@ import android.view.View.OnClickListener;
22 22
 import android.widget.ArrayAdapter;
23 23
 import android.widget.Button;
24 24
 import android.widget.ListView;
25
+import com.flurry.android.FlurryAgent;
25 26
 import java.util.List;
26 27
 
27 28
 import uk.co.md87.android.activityrecorder.rpc.ActivityRecorderBinder;
@@ -77,12 +78,14 @@ public class ActivityRecorderActivity extends Activity {
77 78
         public void onClick(View arg0) {
78 79
             try {
79 80
                 if (service.isRunning()) {
81
+                    FlurryAgent.onEvent("recording_stop");
80 82
                     stopService(new Intent(ActivityRecorderActivity.this,
81 83
                             RecorderService.class));
82 84
                     unbindService(connection);
83 85
                     bindService(new Intent(ActivityRecorderActivity.this, RecorderService.class),
84 86
                             connection, BIND_AUTO_CREATE);
85 87
                 } else {
88
+                    FlurryAgent.onEvent("recording_start");
86 89
                     handler.removeCallbacks(updateRunnable);
87 90
                     ((Button) findViewById(R.id.togglebutton)).setEnabled(false);
88 91
 
@@ -175,4 +178,20 @@ public class ActivityRecorderActivity extends Activity {
175 178
         return ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).getDeviceId();
176 179
     }
177 180
 
181
+    /** {@inheritDoc} */
182
+    @Override
183
+    protected void onStart() {
184
+        super.onStart();
185
+
186
+        FlurryAgent.onStartSession(this, "EMKSQFUWSCW51AKBL2JJ");
187
+    }
188
+
189
+    /** {@inheritDoc} */
190
+    @Override
191
+    protected void onStop() {
192
+        super.onStop();
193
+
194
+        FlurryAgent.onEndSession(this);
195
+    }
196
+
178 197
 }

+ 2
- 2
code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/ClassifierService.java Vedi File

@@ -51,7 +51,7 @@ public class ClassifierService extends Service implements Runnable {
51 51
     public void onStart(Intent intent, int startId) {
52 52
         super.onStart(intent, startId);
53 53
 
54
-        Log.i(getClass().getName(), "Starting classifier");
54
+        //Log.i(getClass().getName(), "Starting classifier");
55 55
 
56 56
         data = intent.getFloatArrayExtra("data");
57 57
 
@@ -111,7 +111,7 @@ public class ClassifierService extends Service implements Runnable {
111 111
 
112 112
         classification = bestActivity;
113 113
 
114
-        Log.i(getClass().getName(), "Classification: " + classification);
114
+        //Log.i(getClass().getName(), "Classification: " + classification);
115 115
 
116 116
         bindService(new Intent(this, RecorderService.class), connection, BIND_AUTO_CREATE);
117 117
     }

+ 10
- 7
code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/R.java Vedi File

@@ -25,15 +25,18 @@ public final class R {
25 25
         public static final int basic_model=0x7f040000;
26 26
     }
27 27
     public static final class string {
28
-        public static final int activity_dancing=0x7f050008;
29
-        public static final int activity_idle_sitting=0x7f05000a;
30
-        public static final int activity_idle_standing=0x7f050009;
28
+        public static final int activity_dancing=0x7f050009;
29
+        public static final int activity_idle=0x7f05000a;
30
+        public static final int activity_idle_sitting=0x7f05000c;
31
+        public static final int activity_idle_standing=0x7f05000b;
31 32
         public static final int activity_unknown=0x7f050004;
32
-        public static final int activity_vehicle_bus=0x7f05000b;
33
-        public static final int activity_vehicle_car=0x7f05000c;
33
+        public static final int activity_vehicle=0x7f05000d;
34
+        public static final int activity_vehicle_bus=0x7f05000e;
35
+        public static final int activity_vehicle_car=0x7f05000f;
34 36
         public static final int activity_walking=0x7f050005;
35
-        public static final int activity_walking_stairs_down=0x7f050007;
36
-        public static final int activity_walking_stairs_up=0x7f050006;
37
+        public static final int activity_walking_stairs=0x7f050006;
38
+        public static final int activity_walking_stairs_down=0x7f050008;
39
+        public static final int activity_walking_stairs_up=0x7f050007;
37 40
         public static final int app_name=0x7f050000;
38 41
         public static final int error_disconnected=0x7f050001;
39 42
         public static final int service_disabled=0x7f050003;

+ 116
- 15
code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/RecorderService.java Vedi File

@@ -22,6 +22,7 @@ import java.io.IOException;
22 22
 import java.io.InputStream;
23 23
 import java.io.ObjectInputStream;
24 24
 import java.util.ArrayList;
25
+import java.util.HashMap;
25 26
 import java.util.List;
26 27
 import java.util.Map;
27 28
 
@@ -34,17 +35,54 @@ import uk.co.md87.android.activityrecorder.rpc.Classification;
34 35
  */
35 36
 public class RecorderService extends Service {
36 37
 
38
+    static final double DELTA = 0.25;
39
+    static final double THRESHOLD = 0.5;
40
+
41
+    private final HashMap<String, HashMap<String, Double>> scores
42
+            = new HashMap<String, HashMap<String, Double>>() {{
43
+        put("", new HashMap<String, Double>() {{
44
+            put("null", 0.5d);
45
+            put("CLASSIFIED", 0.5d);
46
+        }});
47
+
48
+        put("CLASSIFIED", new HashMap<String, Double>() {{
49
+            put("null", 0.2d);
50
+            put("DANCING", 0.2d);
51
+            put("WALKING", 0.2d);
52
+            put("VEHICLE", 0.2d);
53
+            put("IDLE", 0.2d);
54
+        }});
55
+
56
+        put("CLASSIFIED/WALKING", new HashMap<String, Double>() {{
57
+            put("null", 0.5d);
58
+            put("STAIRS", 0.5d);
59
+        }});
60
+
61
+        put("CLASSIFIED/VEHICLE", new HashMap<String, Double>() {{
62
+            put("null", 0.333d);
63
+            put("CAR", 0.333d);
64
+            put("BUS", 0.333d);
65
+        }});
66
+
67
+        put("CLASSIFIED/IDLE", new HashMap<String, Double>() {{
68
+            put("null", 0.333d);
69
+            put("STANDING", 0.333d);
70
+            put("SITTING", 0.333d);
71
+        }});
72
+
73
+        put("CLASSIFIED/WALKING/STAIRS", new HashMap<String, Double>() {{
74
+            put("null", 0.333d);
75
+            put("UP", 0.333d);
76
+            put("DOWN", 0.333d);
77
+        }});
78
+    }};
79
+
37 80
     private final ActivityRecorderBinder.Stub binder = new ActivityRecorderBinder.Stub() {
38 81
 
39 82
         public void submitClassification(String classification) throws RemoteException {
40
-            Log.i(getClass().getName(), "Adding classification: " + classification);
83
+            //Log.i(getClass().getName(), "Received classification: " + classification);
41 84
 
42
-            if (!classifications.isEmpty() && classification.equals(classifications
43
-                    .get(classifications.size() - 1).getClassification())) {
44
-                classifications.get(classifications.size() - 1).updateEnd(System.currentTimeMillis());
45
-            } else {
46
-                classifications.add(new Classification(classification, System.currentTimeMillis()));
47
-            }
85
+            updateScores(classification);
48 86
         }
49 87
 
50 88
         public List<Classification> getClassifications() throws RemoteException {
@@ -111,7 +149,7 @@ public class RecorderService extends Service {
111 149
     }
112 150
 
113 151
     public void sample() {
114
-        Log.i(getClass().getName(), "Sampling");
152
+        //Log.i(getClass().getName(), "Sampling");
115 153
         data[(nextSample * 2) % 256] = values[0];
116 154
         data[(nextSample * 2 + 1) % 256] = values[1];
117 155
         
@@ -120,17 +158,15 @@ public class RecorderService extends Service {
120 158
             System.arraycopy(data, 0, cache, 0, 256);
121 159
             analyse(cache);
122 160
 
123
-            if (nextSample == 192) {
124
-                unregister();
125
-                return;
126
-            }
161
+            unregister();
162
+            return;
127 163
         }
128 164
 
129 165
         handler.postDelayed(sampleRunnable, 50);
130 166
     }
131 167
 
132 168
     public void analyse(float[] data) {
133
-        Log.i(getClass().getName(), "Analysing");
169
+        //Log.i(getClass().getName(), "Analysing");
134 170
         final Intent intent = new Intent(this, ClassifierService.class);
135 171
         intent.putExtra("data", data);
136 172
         startService(intent);
@@ -174,23 +210,88 @@ public class RecorderService extends Service {
174 210
         manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
175 211
         handler.postDelayed(registerRunnable, 1000);
176 212
 
213
+        classifications.add(new Classification("", System.currentTimeMillis()));
214
+
177 215
         wl.acquire();
178 216
     }
179 217
 
180 218
     void register() {
181
-        Log.i(getClass().getName(), "Registering");
219
+        //Log.i(getClass().getName(), "Registering");
182 220
         nextSample = 0;
183 221
         manager.registerListener(accelListener,
184 222
                 manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
185 223
                 SensorManager.SENSOR_DELAY_FASTEST);
186 224
         handler.postDelayed(sampleRunnable, 50);
187
-        handler.postDelayed(registerRunnable, 60000);
225
+        handler.postDelayed(registerRunnable, 30000);
188 226
     }
189 227
 
190 228
     void unregister() {
191 229
         manager.unregisterListener(accelListener);
192 230
     }
193 231
 
232
+    void updateScores(final String classification) {
233
+        String path = "";
234
+
235
+        for (String part : classification.split("/")) {
236
+            if (!scores.containsKey(path)) {
237
+                throw new RuntimeException("Path not found: " + path
238
+                        + " (classification: " + classification + ")");
239
+            }
240
+
241
+            updateScores(scores.get(path), part);
242
+            path = path + (path.length() == 0 ? "" : "/") + part;
243
+        }
244
+
245
+        if (scores.containsKey(path)) {
246
+            // This classification has children which we're not using
247
+            // e.g. we've received CLASSIFIED/WALKING, but we're not walking
248
+            //      up or down stairs
249
+            updateScores(scores.get(path), "null");
250
+        }
251
+
252
+        final String best = getClassification();
253
+
254
+        if (!classifications.isEmpty() && best.equals(classifications
255
+                    .get(classifications.size() - 1).getClassification())) {
256
+            classifications.get(classifications.size() - 1).updateEnd(System.currentTimeMillis());
257
+        } else {
258
+            classifications.add(new Classification(best, System.currentTimeMillis()));
259
+        }
260
+    }
261
+
262
+    String getClassification() {
263
+        String path = "";
264
+
265
+        do {
266
+            final Map<String, Double> map = scores.get(path);
267
+            double best = THRESHOLD;
268
+            String bestPath = "null";
269
+
270
+            for (Map.Entry<String, Double> entry : map.entrySet()) {
271
+                if (entry.getValue() >= best) {
272
+                    best = entry.getValue();
273
+                    bestPath = entry.getKey();
274
+                }
275
+            }
276
+
277
+            path = path + (path.length() == 0 ? "" : "/") + bestPath;
278
+        } while (scores.containsKey(path));
279
+
280
+        return path.replaceAll("(^CLASSIFIED)?/?null$", "");
281
+    }
282
+
283
+    void updateScores(final Map<String, Double> map, final String target) {
284
+        for (Map.Entry<String, Double> entry : map.entrySet()) {
285
+            //Log.d(getClass().getName(), "Score for " + entry.getKey() + " was: " + entry.getValue());
286
+            entry.setValue(entry.getValue() * (1 - DELTA));
287
+
288
+            if (entry.getKey().equals(target)) {
289
+                entry.setValue(entry.getValue() + DELTA);
290
+            }
291
+            //Log.d(getClass().getName(), "Score for " + entry.getKey() + " is now: " + entry.getValue());
292
+        }
293
+    }
294
+
194 295
     @Override
195 296
     public void onDestroy() {
196 297
         super.onDestroy();

+ 4
- 3
code/ActivityRecorder/src/uk/co/md87/android/activityrecorder/rpc/Classification.java Vedi File

@@ -55,7 +55,7 @@ public class Classification implements Parcelable {
55 55
         final int length = (int) ((end - start) / 1000);
56 56
 
57 57
         if (length < 60) {
58
-            duration = length + " secs";
58
+            duration = "<1 min";
59 59
         } else if (length < 60 * 60) {
60 60
             duration = (length / 60) + " mins";
61 61
         } else {
@@ -73,8 +73,9 @@ public class Classification implements Parcelable {
73 73
     }
74 74
 
75 75
     public Classification withContext(final Context context) {
76
-        String name = "activity_" + getClassification().substring(11)
77
-                .replace("/", "_").toLowerCase();
76
+        String name = "activity" + (getClassification().length() == 0
77
+                ? "_unknown" : getClassification().substring(10)
78
+                .replace("/", "_").toLowerCase());
78 79
 
79 80
         niceClassification = context.getResources().getText(
80 81
                 context.getResources().getIdentifier(name, "string",

+ 1
- 1
code/SensorLogger/AndroidManifest.xml Vedi File

@@ -1,6 +1,6 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2 2
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
-     package="uk.co.md87.android.sensorlogger" android:versionCode="16" android:versionName="0.2.3">
3
+     package="uk.co.md87.android.sensorlogger" android:versionCode="17" android:versionName="0.2.4">
4 4
     <application android:label="Sensor Logger" android:icon="@drawable/icon">
5 5
         <activity android:name=".activities.IntroActivity" android:label="Sensor Logger">
6 6
             <intent-filter>

+ 3
- 0
code/SensorLogger/build.xml Vedi File

@@ -18,5 +18,8 @@
18 18
 
19 19
     <target depends="init,compile,-pre-jar,-dex,-package-res-and-assets,-package-res-no-assets,-package-dex,-build-without-signing,-post-jar" description="Build unsigned JAR." name="unsigned-jar"/>
20 20
 
21
+    <target name="-pre-jar">
22
+       <unzip src="lib/FlurryAgent.jar" dest="${build.classes.dir}" overwrite="true"/>
23
+    </target>
21 24
 
22 25
 </project>

BIN
code/SensorLogger/dist/SensorLogger.apk Vedi File


BIN
code/SensorLogger/lib/FlurryAgent.jar Vedi File


+ 3
- 1
code/SensorLogger/nbproject/project.properties Vedi File

@@ -17,10 +17,12 @@ dist.apk=${dist.dir}/SensorLogger.apk
17 17
 dist.dir=dist
18 18
 dist.javadoc.dir=${dist.dir}/javadoc
19 19
 excludes=
20
+file.reference.FlurryAgent.jar=lib/FlurryAgent.jar
20 21
 gen.source.dir=${src.dir}
21 22
 includes=**
22 23
 intermediate.dex=${build.dir}/classes.dex
23
-javac.classpath=
24
+javac.classpath=\
25
+    ${file.reference.FlurryAgent.jar}
24 26
 # Space-separated list of extra javac options
25 27
 javac.compilerargs=
26 28
 javac.deprecation=false

+ 18
- 0
code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/CountdownActivity.java Vedi File

@@ -11,6 +11,7 @@ import android.os.Handler;
11 11
 import android.os.RemoteException;
12 12
 import android.util.Log;
13 13
 import android.widget.TextView;
14
+import com.flurry.android.FlurryAgent;
14 15
 import java.util.TimerTask;
15 16
 
16 17
 import uk.co.md87.android.sensorlogger.R;
@@ -57,6 +58,7 @@ public class CountdownActivity extends BoundActivity {
57 58
             if (time > 0) {
58 59
                 handler.postDelayed(task, 500);
59 60
             } else {
61
+                FlurryAgent.onEvent("countdown_to_recording");
60 62
                 startActivity(new Intent(this, RecordingActivity.class));
61 63
                 finish();
62 64
             }
@@ -65,4 +67,20 @@ public class CountdownActivity extends BoundActivity {
65 67
         }
66 68
     }
67 69
 
70
+    /** {@inheritDoc} */
71
+    @Override
72
+    protected void onStart() {
73
+        super.onStart();
74
+
75
+        FlurryAgent.onStartSession(this, "TFBJJPQUQX3S1Q6IUHA6");
76
+    }
77
+
78
+    /** {@inheritDoc} */
79
+    @Override
80
+    protected void onStop() {
81
+        super.onStop();
82
+
83
+        FlurryAgent.onEndSession(this);
84
+    }
85
+
68 86
 }

+ 19
- 0
code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/IntroActivity.java Vedi File

@@ -14,6 +14,7 @@ import android.util.Log;
14 14
 import android.view.View;
15 15
 import android.view.View.OnClickListener;
16 16
 import android.widget.Button;
17
+import com.flurry.android.FlurryAgent;
17 18
 import uk.co.md87.android.common.ExceptionHandler;
18 19
 
19 20
 import uk.co.md87.android.sensorlogger.R;
@@ -54,6 +55,8 @@ public class IntroActivity extends BoundActivity implements OnClickListener {
54 55
     @Override
55 56
     public void onClick(final View arg0) {
56 57
         try {
58
+            FlurryAgent.onEvent("intro_to_countdown");
59
+
57 60
             service.setState(2);
58 61
             startActivity(new Intent(this, CountdownActivity.class));
59 62
             finish();
@@ -62,4 +65,20 @@ public class IntroActivity extends BoundActivity implements OnClickListener {
62 65
         }
63 66
     }
64 67
 
68
+    /** {@inheritDoc} */
69
+    @Override
70
+    protected void onStart() {
71
+        super.onStart();
72
+        
73
+        FlurryAgent.onStartSession(this, "TFBJJPQUQX3S1Q6IUHA6");
74
+    }
75
+
76
+    /** {@inheritDoc} */
77
+    @Override
78
+    protected void onStop() {
79
+        super.onStop();
80
+
81
+        FlurryAgent.onEndSession(this);
82
+    }
83
+
65 84
 }

+ 18
- 0
code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/RecordingActivity.java Vedi File

@@ -11,6 +11,7 @@ import android.os.Handler;
11 11
 import android.os.RemoteException;
12 12
 import android.util.Log;
13 13
 import android.widget.TextView;
14
+import com.flurry.android.FlurryAgent;
14 15
 import java.util.TimerTask;
15 16
 
16 17
 import uk.co.md87.android.sensorlogger.R;
@@ -76,6 +77,7 @@ public class RecordingActivity extends BoundActivity {
76 77
             }
77 78
 
78 79
             if (serviceState > 4) {
80
+                FlurryAgent.onEvent("countdown_to_results");
79 81
                 startActivity(new Intent(this, ResultsActivity.class));
80 82
                 finish();
81 83
             } else {
@@ -86,4 +88,20 @@ public class RecordingActivity extends BoundActivity {
86 88
         }
87 89
     }
88 90
 
91
+    /** {@inheritDoc} */
92
+    @Override
93
+    protected void onStart() {
94
+        super.onStart();
95
+
96
+        FlurryAgent.onStartSession(this, "TFBJJPQUQX3S1Q6IUHA6");
97
+    }
98
+
99
+    /** {@inheritDoc} */
100
+    @Override
101
+    protected void onStop() {
102
+        super.onStop();
103
+
104
+        FlurryAgent.onEndSession(this);
105
+    }
106
+
89 107
 }

+ 25
- 0
code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/ResultsActivity.java Vedi File

@@ -19,6 +19,7 @@ import android.widget.ArrayAdapter;
19 19
 import android.widget.AutoCompleteTextView;
20 20
 import android.widget.Button;
21 21
 import android.widget.TextView;
22
+import com.flurry.android.FlurryAgent;
22 23
 import java.util.TimerTask;
23 24
 
24 25
 import uk.co.md87.android.sensorlogger.R;
@@ -43,6 +44,8 @@ public class ResultsActivity extends BoundActivity {
43 44
     private final OnClickListener yesListener = new OnClickListener() {
44 45
 
45 46
         public void onClick(View arg0) {
47
+            FlurryAgent.onEvent("results_yes_click");
48
+
46 49
             findViewById(R.id.resultsno).setEnabled(false);
47 50
             findViewById(R.id.resultsyes).setEnabled(false);
48 51
 
@@ -60,6 +63,8 @@ public class ResultsActivity extends BoundActivity {
60 63
             = new DialogInterface.OnClickListener() {
61 64
 
62 65
         public void onClick(DialogInterface arg0, int arg1) {
66
+            FlurryAgent.onEvent("results_correction_submitted");
67
+
63 68
             dialog = ProgressDialog.show(ResultsActivity.this, "Please wait",
64 69
                     "Submitting...", true);
65 70
             
@@ -75,6 +80,8 @@ public class ResultsActivity extends BoundActivity {
75 80
     private final OnClickListener noListener = new OnClickListener() {
76 81
 
77 82
         public void onClick(View arg0) {
83
+            FlurryAgent.onEvent("results_no_click");
84
+
78 85
             findViewById(R.id.resultsno).setEnabled(false);
79 86
             findViewById(R.id.resultsyes).setEnabled(false);
80 87
 
@@ -132,6 +139,8 @@ public class ResultsActivity extends BoundActivity {
132 139
     void checkStage() {
133 140
         try {
134 141
             if (service.getState() == 7) {
142
+                FlurryAgent.onEvent("results_to_thanks");
143
+
135 144
                 service.setState(8);
136 145
                 startActivity(new Intent(this, ThanksActivity.class));
137 146
                 finish();
@@ -143,4 +152,20 @@ public class ResultsActivity extends BoundActivity {
143 152
         }
144 153
     }
145 154
 
155
+    /** {@inheritDoc} */
156
+    @Override
157
+    protected void onStart() {
158
+        super.onStart();
159
+
160
+        FlurryAgent.onStartSession(this, "TFBJJPQUQX3S1Q6IUHA6");
161
+    }
162
+
163
+    /** {@inheritDoc} */
164
+    @Override
165
+    protected void onStop() {
166
+        super.onStop();
167
+
168
+        FlurryAgent.onEndSession(this);
169
+    }
170
+
146 171
 }

+ 17
- 0
code/SensorLogger/src/uk/co/md87/android/sensorlogger/activities/ThanksActivity.java Vedi File

@@ -9,6 +9,7 @@ import android.app.Activity;
9 9
 import android.os.Bundle;
10 10
 import android.telephony.TelephonyManager;
11 11
 import android.widget.TextView;
12
+import com.flurry.android.FlurryAgent;
12 13
 
13 14
 import uk.co.md87.android.sensorlogger.R;
14 15
 
@@ -51,4 +52,20 @@ public class ThanksActivity extends Activity {
51 52
         return builder.toString();
52 53
     }
53 54
 
55
+    /** {@inheritDoc} */
56
+    @Override
57
+    protected void onStart() {
58
+        super.onStart();
59
+
60
+        FlurryAgent.onStartSession(this, "TFBJJPQUQX3S1Q6IUHA6");
61
+    }
62
+
63
+    /** {@inheritDoc} */
64
+    @Override
65
+    protected void onStop() {
66
+        super.onStop();
67
+
68
+        FlurryAgent.onEndSession(this);
69
+    }
70
+
54 71
 }

+ 11
- 0
website/index.html Vedi File

@@ -74,6 +74,7 @@
74 74
        </p>
75 75
        <h4>Changelog</h4>
76 76
        <ul>
77
+        <li><strong>0.2.3 &rarr; 0.2.4</strong>: Added analytics</li>
77 78
         <li><strong>0.2.2 &rarr; 0.2.3</strong>: Fix another force close, updated model for classification</li>
78 79
         <li><strong>0.2.1 &rarr; 0.2.2</strong>: Fix force close, add reporting of exceptions</li>
79 80
         <li><strong>0.2.0 &rarr; 0.2.1</strong>: Bug fix related to turning display off</li>
@@ -112,8 +113,18 @@
112 113
         integrated, and the service will eventually provide an API for other
113 114
         applications to listen out for changes in the user's activity.
114 115
        </p>
116
+       <p>
117
+        The classification algorithm now uses scores assigned to each possible
118
+        classification instead of merely using the results from the last
119
+        set of sensor input. This means that the classifications may be
120
+        slightly delayed (it will take a minute or so to react to changes in
121
+        activity), but it makes the algorithm much more tolerant of occasional
122
+        erroneous readings.
123
+       </p>
115 124
        <h4>Changelog</h4>
116 125
        <ul>
126
+        <li><strong>0.2.0 &rarr; 0.2.1</strong>: Added analytics</li>
127
+        <li><strong>0.1.3 &rarr; 0.2.0</strong>: Changed classification algorithm to favour existing classifications, change recording to one sample every 30 seconds instead of 2 overlapping samples every 60 seconds, disable logging, durations measured in seconds now show as "&lt;1 min"</li>
117 128
         <li><strong>0.1.2 &rarr; 0.1.3</strong>: More efficient updating of activity list, give feedback when starting service</li>
118 129
         <li><strong>0.1.1 &rarr; 0.1.2</strong>: Fix various issues when starting service</li>
119 130
         <li><strong>0.1.0 &rarr; 0.1.1</strong>: Fix exception when stopping service in some conditions</li>

Loading…
Annulla
Salva