Quellcode durchsuchen

Proper location handling

master
Chris Smith vor 14 Jahren
Ursprung
Commit
b17a096724

+ 1
- 1
code/Common/BaseFactory.java Datei anzeigen

@@ -31,7 +31,7 @@ import android.os.Build;
31 31
 public abstract class BaseFactory {
32 32
 
33 33
     protected boolean shouldUseFake() {
34
-        return "sdk".equals(Build.PRODUCT);
34
+        return Build.PRODUCT.endsWith("sdk");
35 35
     }
36 36
 
37 37
 }

BIN
code/ContextAnalyser/dist/ContextAnalyser.apk Datei anzeigen


+ 89
- 3
code/ContextAnalyser/src/uk/co/md87/android/contextanalyser/ContextAnalyserService.java Datei anzeigen

@@ -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

+ 41
- 1
code/ContextAnalyser/src/uk/co/md87/android/contextanalyser/DataHelper.java Datei anzeigen

@@ -28,6 +28,9 @@ import android.database.sqlite.SQLiteDatabase;
28 28
 import android.database.sqlite.SQLiteOpenHelper;
29 29
 import android.database.sqlite.SQLiteStatement;
30 30
 import android.location.Location;
31
+import android.util.Log;
32
+import java.util.HashMap;
33
+import java.util.Map;
31 34
 
32 35
 /**
33 36
  *
@@ -41,10 +44,13 @@ public class DataHelper {
41 44
 
42 45
     private static final String INSERT_LOCATION = "insert into "
43 46
       + LOCATIONS_TABLE + "(name, lat, lon) values (?, ?, ?)";
47
+    private static final String UPDATE_LOCATION = "update "
48
+      + LOCATIONS_TABLE + " set name = ? where id = ?";
49
+    private static final String UNNAMED_QUERY = "name LIKE '%.%,%.%'";
44 50
     private static final String LOCATION_QUERY = "lat > %1$s - 0.005 and "
45 51
             + "lat < %1$s + 0.005 and lon > %2$s - 0.01 and lon < %2$s + 0.01";
46 52
 
47
-    private final SQLiteStatement insertLocationStatement;
53
+    private final SQLiteStatement insertLocationStatement, updateLocationStatement;
48 54
 
49 55
     private final Context context;
50 56
     private SQLiteDatabase db;
@@ -55,15 +61,44 @@ public class DataHelper {
55 61
         final OpenHelper helper = new OpenHelper(context);
56 62
         this.db = helper.getWritableDatabase();
57 63
         this.insertLocationStatement = db.compileStatement(INSERT_LOCATION);
64
+        this.updateLocationStatement = db.compileStatement(UPDATE_LOCATION);
58 65
     }
59 66
 
60 67
     public long addLocation(final String name, final double lat, final double lon) {
68
+        Log.i(getClass().getSimpleName(), "Adding new place at " + lat + ", " + lon);
61 69
         insertLocationStatement.bindString(1, name);
62 70
         insertLocationStatement.bindDouble(2, lat);
63 71
         insertLocationStatement.bindDouble(3, lon);
64 72
         return insertLocationStatement.executeInsert();
65 73
     }
66 74
 
75
+    public void updateLocation(final long id, final String name) {
76
+        Log.i(getClass().getSimpleName(), "Setting name of place " + id + " to " + name);
77
+        updateLocationStatement.bindString(1, name);
78
+        updateLocationStatement.bindLong(2, id);
79
+        updateLocationStatement.execute();
80
+    }
81
+
82
+    public Map<String, Long> getUnnamedLocations() {
83
+        final Map<String, Long> results = new HashMap<String, Long>();
84
+        
85
+        final Cursor cursor = db.query(LOCATIONS_TABLE,
86
+                new String[] { "id", "name" },
87
+                UNNAMED_QUERY, null, null, null, null);
88
+        
89
+        if (cursor.moveToFirst()) {
90
+            do {
91
+                results.put(cursor.getString(1), cursor.getLong(0));
92
+            } while (cursor.moveToNext());
93
+        }
94
+
95
+        if (cursor != null && !cursor.isClosed()) {
96
+            cursor.close();
97
+        }
98
+
99
+        return results;
100
+    }
101
+
67 102
     public LocationResult findLocation(final double lat, final double lon) {
68 103
         final Cursor cursor = db.query(LOCATIONS_TABLE,
69 104
                 new String[] { "id", "name", "lat", "lon" },
@@ -117,6 +152,11 @@ public class DataHelper {
117 152
             return name;
118 153
         }
119 154
 
155
+        @Override
156
+        public String toString() {
157
+            return "LocationResult{id=" + id + "name=" + name + "lat=" + lat + "lon=" + lon + '}';
158
+        }
159
+
120 160
     }
121 161
 
122 162
     private static class OpenHelper extends SQLiteOpenHelper {

+ 0
- 1
code/ContextAnalyser/src/uk/co/md87/android/contextanalyser/IntroActivity.java Datei anzeigen

@@ -36,7 +36,6 @@ public class IntroActivity extends Activity {
36 36
     @Override
37 37
     public void onCreate(Bundle icicle) {
38 38
         super.onCreate(icicle);
39
-        // ToDo add your GUI initialization code here
40 39
 
41 40
         startService(new Intent(this, ContextAnalyserService.class));
42 41
     }

Laden…
Abbrechen
Speichern