· 9 years ago · Oct 27, 2016, 09:32 AM
1public class LocationsDB extends SQLiteOpenHelper{
2
3 /** Database name */
4 private static String DBNAME = "MapsActivity";
5
6 /** Version number of the database */
7 private static int VERSION = 1;
8
9 /** Field 1 of the table locations, which is the primary key */
10 public static final String FIELD_ROW_ID = "_id";
11
12 /** Field 2 of the table locations, stores the latitude */
13 public static final String FIELD_LAT = "lat";
14
15 /** Field 3 of the table locations, stores the longitude*/
16 public static final String FIELD_LNG = "lng";
17
18 /** Field 4 of the table locations, stores the zoom level of map*/
19 public static final String FIELD_ZOOM = "zom";
20
21 /** A constant, stores the the table name */
22 private static final String DATABASE_TABLE = "locations";
23
24 /** An instance variable for SQLiteDatabase */
25 private SQLiteDatabase mDB;
26
27 /** Constructor */
28 public LocationsDB(Context context) {
29 super(context, DBNAME, null, VERSION);
30 this.mDB = getWritableDatabase();
31 }
32
33 /** This is a callback method, invoked when the method getReadableDatabase() / getWritableDatabase() is called
34 * provided the database does not exists
35 * */
36 @Override
37 public void onCreate(SQLiteDatabase db) {
38 String sql = "create table " + DATABASE_TABLE + " ( " +
39 FIELD_ROW_ID + " integer primary key autoincrement , " +
40 FIELD_LNG + " double , " +
41 FIELD_LAT + " double , " +
42 FIELD_ZOOM + " text " +
43 " ) ";
44
45 db.execSQL(sql);
46 }
47
48 /** Inserts a new location to the table locations */
49 public long insert(ContentValues contentValues){
50 long rowID = mDB.insert(DATABASE_TABLE, null, contentValues);
51 return rowID;
52 }
53
54 /** Deletes all locations from the table */
55 public int del(){
56 int cnt = mDB.delete(DATABASE_TABLE, null , null);
57 return cnt;
58 }
59
60 /** Returns all the locations from the table */
61 public Cursor getAllLocations(){
62 return mDB.query(DATABASE_TABLE, new String[] { FIELD_ROW_ID, FIELD_LAT , FIELD_LNG, FIELD_ZOOM } , null, null, null, null, null);
63 }
64
65 @Override
66 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
67 }
68
69}
70
71private static final String TAG = "MapsActivity";
72 private static final long INTERVAL = 30000;
73 private static final long FASTEST_INTERVAL = 30000;
74 private static final float SMALLEST_DISPLACEMENT = 0.10F;
75 ImageButton buttonCurrent;
76 ImageButton buttonStop;
77 LocationRequest mLocationRequest;
78 GoogleApiClient mGoogleApiClient;
79 Location mCurrentLocation;
80 String mLastUpdateTime;
81 GoogleMap googleMap;
82 Polyline line;
83 private ArrayList<LatLng> points;
84
85 protected void createLocationRequest() {
86 mLocationRequest = new LocationRequest();
87 mLocationRequest.setInterval(INTERVAL);
88 mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
89 mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
90 mLocationRequest.setSmallestDisplacement(SMALLEST_DISPLACEMENT); //added
91 }
92
93 @Override
94 protected void onCreate(Bundle savedInstanceState) {
95 super.onCreate(savedInstanceState);
96 points = new ArrayList<>();
97
98 Log.d(TAG, "onCreate ...............................");
99 //show error dialog if GoolglePlayServices not available
100 if (!isGooglePlayServicesAvailable()) {
101 finish();
102 }
103 createLocationRequest();
104 mGoogleApiClient = new GoogleApiClient.Builder(this)
105 .addApi(LocationServices.API)
106 .addConnectionCallbacks(this)
107 .addOnConnectionFailedListener(this)
108 .build();
109
110 setContentView(R.layout.activity_maps);
111 SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager()
112 .findFragmentById(R.id.map);
113 googleMap = fm.getMap();
114 googleMap.getUiSettings().setZoomControlsEnabled(true);
115 buttonCurrent = (ImageButton) findViewById(R.id.buttonCurrent);
116 buttonStop = (ImageButton) findViewById(R.id.buttonStop);
117 buttonCurrent.setOnClickListener(this);
118 buttonStop.setOnClickListener(this);
119 getSupportLoaderManager().initLoader(0, null, this);
120 }
121
122 @Override
123 public void onStart() {
124 super.onStart();
125 Log.d(TAG, "onStart fired ..............");
126 mGoogleApiClient.connect();
127 }
128
129 @Override
130 public void onStop() {
131 super.onStop();
132 Log.d(TAG, "onStop fired ..............");
133 mGoogleApiClient.disconnect();
134 Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
135 }
136
137 private boolean isGooglePlayServicesAvailable() {
138 int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
139 if (ConnectionResult.SUCCESS == status) {
140 return true;
141 } else {
142 GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
143 return false;
144 }
145 }
146
147 @Override
148 public void onConnected(Bundle bundle) {
149 Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
150 startLocationUpdates();
151 }
152
153 protected void startLocationUpdates() {
154 PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
155 mGoogleApiClient, mLocationRequest, this);
156 Log.d(TAG, "Location update started ..............: ");
157 }
158
159 @Override
160 public void onConnectionSuspended(int i) {
161
162 }
163
164 @Override
165 public void onConnectionFailed(ConnectionResult connectionResult) {
166 Log.d(TAG, "Connection failed: " + connectionResult.toString());
167 }
168
169 @Override
170 public void onLocationChanged(Location location) {
171 Log.d(TAG, "Firing onLocationChanged..............................................");
172 mCurrentLocation = location;
173 mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
174 addMarker();
175 float accuracy = location.getAccuracy();
176 Log.d("iFocus", "The amount of accuracy is " + accuracy);
177 double latitude = location.getLatitude();
178 double longitude = location.getLongitude();
179 LatLng latLng = new LatLng(latitude, longitude);
180 points.add(latLng);
181 redrawLine();
182
183 }
184
185 private void redrawLine() {
186
187 googleMap.clear(); //clears all Markers and Polylines
188
189 PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
190 for (int i = 0; i < points.size(); i++) {
191 LatLng point = points.get(i);
192 options.add(point);
193 }
194 addMarker();
195 line = googleMap.addPolyline(options);
196 }
197
198 private void addMarker() {
199 MarkerOptions options = new MarkerOptions();
200 // following four lines requires 'Google Maps Android API Utility Library'
201 // https://developers.google.com/maps/documentation/android/utility/
202 // I have used this to display the time as title for location markers
203 // you can safely comment the following four lines but for this info
204 IconGenerator iconFactory = new IconGenerator(this);
205 iconFactory.setStyle(IconGenerator.STYLE_PURPLE);
206 options.icon(BitmapDescriptorFactory.fromBitmap(iconFactory.makeIcon(mLastUpdateTime)));
207 options.anchor(iconFactory.getAnchorU(), iconFactory.getAnchorV());
208 LatLng currentLatLng = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
209 options.position(currentLatLng);
210 Marker mapMarker = googleMap.addMarker(options);
211 long atTime = mCurrentLocation.getTime();
212 mLastUpdateTime = DateFormat.getTimeInstance().format(new Date(atTime));
213 mapMarker.setTitle(mLastUpdateTime);
214 Log.d(TAG, "Marker added.............................");
215 googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng,
216 13));
217 Log.d(TAG, "Zoom done.............................");
218 }
219 private class LocationInsertTask extends AsyncTask<ContentValues, Void, Void>{
220 @Override
221 protected Void doInBackground(ContentValues... contentValues) {
222 /** Setting up values to insert the clicked location into SQLite database */
223 getContentResolver().insert(LocationsContentProvider.CONTENT_URI, contentValues[0]);
224 return null;
225 }
226 }
227
228 private class LocationDeleteTask extends AsyncTask<Void, Void, Void> {
229 @Override
230 protected Void doInBackground(Void... params) {
231
232 /** Deleting all the locations stored in SQLite database */
233 getContentResolver().delete(LocationsContentProvider.CONTENT_URI, null, null);
234 return null;
235 }
236 }
237 @Override
238 protected void onPause() {
239 super.onPause();
240 stopLocationUpdates();
241 }
242
243 protected void stopLocationUpdates() {
244 LocationServices.FusedLocationApi.removeLocationUpdates(
245 mGoogleApiClient, this);
246 Log.d(TAG, "Location update stopped .......................");
247 }
248
249 @Override
250 public void onResume() {
251 super.onResume();
252 if (mGoogleApiClient.isConnected()) {
253 startLocationUpdates();
254 Log.d(TAG, "Location update resumed .....................");
255 }
256 }
257
258 @Override
259 public void onClick(View v) {
260 switch (v.getId()) {
261 case R.id.buttonCurrent:
262 startLocationUpdates();
263 break;
264 case R.id.buttonStop:
265 stopLocationUpdates();
266 break;
267 case R.id.buttonReplay:
268 OnButtonReplay();
269 break;
270 }
271 }
272
273 private void OnButtonReplay() {
274
275 }
276
277 @Override
278 public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
279
280 // Uri to the content provider LocationsContentProvider
281 Uri uri = LocationsContentProvider.CONTENT_URI;
282
283 // Fetches all the rows from locations table
284 return new CursorLoader(this, uri, null, null, null, null);
285 }
286
287 @Override
288 public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
289 int locationCount = 0;
290 double lat=0;
291 double lng=0;
292 float zoom=0;
293
294 // Number of locations available in the SQLite database table
295 locationCount = arg1.getCount();
296
297 // Move the current record pointer to the first row of the table
298 arg1.moveToFirst();
299
300 for(int i=0;i<locationCount;i++){
301
302 // Get the latitude
303 lat = arg1.getDouble(arg1.getColumnIndex(LocationsDB.FIELD_LAT));
304
305 // Get the longitude
306 lng = arg1.getDouble(arg1.getColumnIndex(LocationsDB.FIELD_LNG));
307
308 // Get the zoom level
309 zoom = arg1.getFloat(arg1.getColumnIndex(LocationsDB.FIELD_ZOOM));
310
311 arg1.moveToNext();
312 }
313
314 if(locationCount>0){
315 // Moving CameraPosition to last clicked position
316 googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(lat,lng)));
317
318 // Setting the zoom level in the map on last position is clicked
319 googleMap.animateCamera(CameraUpdateFactory.zoomTo(zoom));
320 }
321 }
322
323
324 @Override
325 public void onLoaderReset(Loader<Cursor> loader) {
326
327 }
328}
329
330public class LocationsContentProvider extends ContentProvider{
331
332 public static final String PROVIDER_NAME = "MapsActivity";
333
334 /** A uri to do operations on locations table. A content provider is identified by its uri */
335 public static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/locations" );
336
337 /** Constant to identify the requested operation */
338 private static final int LOCATIONS = 1;
339
340 private static final UriMatcher uriMatcher ;
341
342 static {
343 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
344 uriMatcher.addURI(PROVIDER_NAME, "locations", LOCATIONS);
345 }
346
347 /** This content provider does the database operations by this object */
348 LocationsDB mLocationsDB;
349
350 /** A callback method which is invoked when the content provider is starting up */
351 @Override
352 public boolean onCreate() {
353 mLocationsDB = new LocationsDB(getContext());
354 return true;
355 }
356
357 /** A callback method which is invoked when insert operation is requested on this content provider */
358 @Override
359 public Uri insert(Uri uri, ContentValues values) {
360 long rowID = mLocationsDB.insert(values);
361 Uri _uri=null;
362 if(rowID>0){
363 _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
364 }else {
365 try {
366 throw new SQLException("Failed to insert : " + uri);
367 } catch (SQLException e) {
368 e.printStackTrace();
369 }
370 }
371 return _uri;
372 }
373
374 @Override
375 public int update(Uri uri, ContentValues values, String selection,
376 String[] selectionArgs) {
377 // TODO Auto-generated method stub
378 return 0;
379 }
380
381 /** A callback method which is invoked when delete operation is requested on this content provider */
382 @Override
383 public int delete(Uri uri, String selection, String[] selectionArgs) {
384 int cnt = 0;
385 cnt = mLocationsDB.del();
386 return cnt;
387 }
388
389 /** A callback method which is invoked by default content uri */
390 @Override
391 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
392
393 if(uriMatcher.match(uri)==LOCATIONS){
394 return mLocationsDB.getAllLocations();
395 }
396 return null;
397 }
398
399 @Override
400 public String getType(Uri uri) {
401 return null;
402 }
403}