|
@@ -24,8 +24,16 @@ package uk.co.md87.android.contextanalyser;
|
24
|
24
|
|
25
|
25
|
import android.app.Service;
|
26
|
26
|
import android.content.Intent;
|
|
27
|
+import android.location.Address;
|
|
28
|
+import android.location.Geocoder;
|
|
29
|
+import android.location.Location;
|
27
|
30
|
import android.os.Handler;
|
28
|
31
|
import android.os.IBinder;
|
|
32
|
+import android.util.Log;
|
|
33
|
+import java.io.IOException;
|
|
34
|
+import java.util.HashMap;
|
|
35
|
+import java.util.Iterator;
|
|
36
|
+import java.util.List;
|
29
|
37
|
|
30
|
38
|
import java.util.Map;
|
31
|
39
|
|
|
@@ -36,6 +44,7 @@ import uk.co.md87.android.common.accel.AccelReaderFactory;
|
36
|
44
|
import uk.co.md87.android.common.accel.Sampler;
|
37
|
45
|
import uk.co.md87.android.common.geo.LocationMonitor;
|
38
|
46
|
import uk.co.md87.android.common.geo.LocationMonitorFactory;
|
|
47
|
+import uk.co.md87.android.contextanalyser.DataHelper.LocationResult;
|
39
|
48
|
|
40
|
49
|
/**
|
41
|
50
|
*
|
|
@@ -43,6 +52,8 @@ import uk.co.md87.android.common.geo.LocationMonitorFactory;
|
43
|
52
|
*/
|
44
|
53
|
public class ContextAnalyserService extends Service {
|
45
|
54
|
|
|
55
|
+ private static final int POLLING_DELAY = 60000;
|
|
56
|
+
|
46
|
57
|
private final Runnable scheduleRunnable = new Runnable() {
|
47
|
58
|
|
48
|
59
|
public void run() {
|
|
@@ -57,8 +68,15 @@ public class ContextAnalyserService extends Service {
|
57
|
68
|
}
|
58
|
69
|
};
|
59
|
70
|
|
60
|
|
- public static Map<Float[], String> model;
|
|
71
|
+ private Map<Float[], String> model;
|
|
72
|
+
|
|
73
|
+ private final Map<String, Long> names = new HashMap<String, Long>();
|
61
|
74
|
|
|
75
|
+ private double lat = 0, lon = 0;
|
|
76
|
+ private int locationCount = 0;
|
|
77
|
+ private LocationResult lastLocation;
|
|
78
|
+ private Geocoder geocoder;
|
|
79
|
+
|
62
|
80
|
private Sampler sampler;
|
63
|
81
|
private Classifier classifier;
|
64
|
82
|
private Aggregator aggregator;
|
|
@@ -75,18 +93,86 @@ public class ContextAnalyserService extends Service {
|
75
|
93
|
classifier = new Classifier(ModelReader.getModel(this, R.raw.basic_model).entrySet());
|
76
|
94
|
aggregator = new Aggregator();
|
77
|
95
|
dataHelper = new DataHelper(this);
|
|
96
|
+ geocoder = new Geocoder(this);
|
78
|
97
|
|
79
|
|
- handler.postDelayed(scheduleRunnable, 60000);
|
|
98
|
+ names.putAll(dataHelper.getUnnamedLocations());
|
|
99
|
+
|
|
100
|
+ handler.postDelayed(scheduleRunnable, POLLING_DELAY);
|
80
|
101
|
}
|
81
|
102
|
|
82
|
103
|
public void poll() {
|
83
|
|
- handler.postDelayed(scheduleRunnable, 60000);
|
|
104
|
+ handler.postDelayed(scheduleRunnable, POLLING_DELAY);
|
|
105
|
+
|
|
106
|
+ Log.v(getClass().getSimpleName(), "Polling...");
|
84
|
107
|
|
85
|
108
|
sampler.start();
|
|
109
|
+
|
|
110
|
+ pollLocation();
|
|
111
|
+ pollGeolocation();
|
|
112
|
+ }
|
|
113
|
+
|
|
114
|
+ protected void pollLocation() {
|
|
115
|
+ final double newLat = locationMonitor.getLat();
|
|
116
|
+ final double newLon = locationMonitor.getLon();
|
|
117
|
+ final float[] distance = new float[1];
|
|
118
|
+ Location.distanceBetween(newLat, newLon, lat, lon, distance);
|
|
119
|
+
|
|
120
|
+ if ((lat == 0 && lon == 0) || distance[0] > 500) {
|
|
121
|
+ // New location
|
|
122
|
+ lat = newLat;
|
|
123
|
+ lon = newLon;
|
|
124
|
+ locationCount = 1;
|
|
125
|
+ lastLocation = dataHelper.findLocation(lat, lon);
|
|
126
|
+
|
|
127
|
+ Log.i(getClass().getSimpleName(), "Location: " + lastLocation);
|
|
128
|
+ } else {
|
|
129
|
+ // Existing location
|
|
130
|
+
|
|
131
|
+ if (++locationCount > 2 && lastLocation == null) {
|
|
132
|
+ // But we don't know it yet - add it!
|
|
133
|
+ final String name = lat + "," + lon;
|
|
134
|
+
|
|
135
|
+ final long id = dataHelper.addLocation(name, lat, lon);
|
|
136
|
+ lastLocation = dataHelper.findLocation(lat, lon);
|
|
137
|
+
|
|
138
|
+ Log.i(getClass().getSimpleName(), "Location (new): " + lastLocation);
|
|
139
|
+
|
|
140
|
+ names.put(name, id);
|
|
141
|
+ }
|
|
142
|
+ }
|
|
143
|
+ }
|
|
144
|
+
|
|
145
|
+ protected void pollGeolocation() {
|
|
146
|
+ final Iterator<Map.Entry<String, Long>> it = names.entrySet().iterator();
|
|
147
|
+ while (it.hasNext()) {
|
|
148
|
+ final Map.Entry<String, Long> tuple = it.next();
|
|
149
|
+
|
|
150
|
+ Log.v(getClass().getSimpleName(), "Attempting to geocode " + tuple.getKey());
|
|
151
|
+
|
|
152
|
+ final String[] parts = tuple.getKey().split(",", 2);
|
|
153
|
+
|
|
154
|
+ try {
|
|
155
|
+ final List<Address> addresses = geocoder.getFromLocation(
|
|
156
|
+ Double.parseDouble(parts[0]), Double.parseDouble(parts[1]), 1);
|
|
157
|
+
|
|
158
|
+ if (addresses != null && !addresses.isEmpty()) {
|
|
159
|
+ // We found a nice address
|
|
160
|
+
|
|
161
|
+ dataHelper.updateLocation(tuple.getValue(),
|
|
162
|
+ addresses.get(0).getAddressLine(0));
|
|
163
|
+
|
|
164
|
+ it.remove();
|
|
165
|
+ }
|
|
166
|
+ } catch (IOException ex) {
|
|
167
|
+ // Do nothing
|
|
168
|
+ }
|
|
169
|
+ }
|
86
|
170
|
}
|
87
|
171
|
|
88
|
172
|
public void analyse() {
|
89
|
173
|
aggregator.addClassification(classifier.classify(sampler.getData()));
|
|
174
|
+
|
|
175
|
+ Log.v(getClass().getSimpleName(), "Aggregator says: " + aggregator.getClassification());
|
90
|
176
|
}
|
91
|
177
|
|
92
|
178
|
@Override
|