POSIT:Coverage Tracker Notes

From Notes

Jump to: navigation, search
   * Last Edited - Tuesday August 31, 2010
   * About - Coverage Tracker 

Contents

Description

POSIT's Coverage Tracker tracks the phone's location by recording its latitude and longitude, saving the GeoPoints in the device's database, and synchronizing the points with the POSIT-server. During tracking, the track (an Expedition) is displayed on a Google map in the Tracker View. Because the Tracker runs as a background Service in an Asynchronous thread, the user can navigate away from the Tracker View to other POSIT activities or to other Android apps. This allows the phone to be tracked while the user continues to collect Finds.

The Tracker requires that GPS is activated on the device. However, it will run regardless of whether the device has network connectivity (WiFi or MOBILE) and it will continue to record GeoPoints when the device's connectivity is intermittent. As GeoPoints are recorded they are first saved to POSIT's database. If the network is connected when the point is recorded, it is sent immediately to the POSIT Server. This allows the Expedition to be displayed in real time at the Server. If the network connection is unavailable when the point is recorded, the point is marked as NOT Synced. Points that are not synced during tracking can be synced later whenever network connectivity is available.

How It Works

Alt
Figure 1: The Tracker menu.

The Tracker is invoked from the main POSIT menu (Figure 1).

Selecting the Tracker menu item starts the TrackerActivity and presents the user with the Tracker View interface. The TrackerActivity and its View run in the foreground and handle all interaction with the user. A View in Android cannot be access from a background thread. This means that TrackerService, running in the background cannot directly manipulate the View.


Alt
Figure 2: The Tracker View.
The Tracker View (Figure 2) consists of a Google map plus a small number of TextViews that display the current state of tracking. These record the Tracker's current status (RUNNING, IDLE), its network connectivity (WiFi, MOBILE, or NONE), its current location (latitude, longitude, altitude), and the number of points recorded.

Interaction with the Tracker View is controlled by three buttons:

  • The Start/Stop Button is used the start and stop the Tracker Service. Its label is changed depending on the Tracker's state (either RUNNING or IDLE). The TrackerService implements a LocationListener. It may take a few seconds -- sometimes a few dozen seconds -- for the listener to get a fix through GPS on the phone's current location. Whenever the phone's location changes by some minimum value -- controlled by the Minimum Recording Distance parameter, the phone's longitude, latitude, altitude, and time are recorded and this information is transmitted to the Tracker View.
Alt
Figure 3: Settings View.
Once the Tracker Service is started, it will continue to run until stopped by the user. The user is free to leave the Tracker Activity and to continue logging finds and to even open up other applications on the phone. When the user would like to stop tracking, they must navigate back to the Tracker View and click the Stop button.
  • The Settings Button brings up the TrackerSettings activity, which allows the user to control certain parameters, including the

Swath width and the Minimum Recording Distance. These can be changed at any time during tracking. Their effect on the Tracker will be immediate. Currently the Swath is not used either on the phone or the server, although its value is included in the data sent to the server.

  • The List Button is used to display Expeditions that were previously recorded. This button is disabled while the Tracker is running.


Tracker Settings

Alt
Figure 4: Minimum distance.
The Settings button brings up an Android Preference View (Figure 3), which allows the user to change the tracking parameters in real time. Both the Swath parameter and the Minimum Recording Distance parameter (Figure 4) use selection menus to limit the user's choices to a fixed range of options. Currently these parameters are stored as SharedDefaultPreferences along with other POSIT preferences.

Listing Expeditions

Alt
Figure 5: Displaying an existing track.

The List button brings up a (rudimentary = needs work) list of the Expeditions currently stored on the phone. When an expedition is selected, it is displayed in the Tracker View. If the recorded expedition contains points that were not yet synced with the server, the user will be presented with a Sync Button, which, when clicked, will transmit the unsynced points to the Server (Figure 5). A background thread is used to transmit points. The button disappears when all points associated with the Expedition have been successfully synced.

When viewing a previously recorded Expedition, the user can use the Delete Button to delete the expedition and all of its recorded points from the phone. Deleting the Expedition from the phone has no effect on the Server, where the expedition will continue to be recorded.





Implementation

POSIT Tracker consists of the following files:

  • TrackerActivity.java -- The main Tracker activity, which controls the User Interface.
  • TrackerBackgroundService.java -- The Tracker service, which manages listening for location updates, saving points to the Db, and syncing points with the server.
  • TrackerListActivity.java -- Displays a selectable list of previously recorded Expeditions.
  • TrackerOverlay.java -- Constructs a Google maps overlay of an Expedition's points.
  • TrackerSettings.java -- The Tracker's settings activity, allows the user to change the Tracker's parameters.
  • TrackerState.java -- The object contains the Expedition's points and other element's of the Expedition's state. This object is passed back and forth between the Service and the Activity.

TrackerActivity

The TrackerActivity controls interaction with the user during tracking. It is responsible for all updates to the View. Control of the activity is handled through buttons (as opposed to menus) and the control code is in the onClick(View) method. As you can see from this code segment, three buttons are used by the Activity and these buttons can have different labels:

	public void onClick(View v) {
		switch (v.getId()) {
		
		case R.id.idTrackerButton:   // The play/stop button

		if (mState == TrackerSettings.IDLE) {  // Start the tracker
			startTrackerService();
			mListButton.setClickable(false);
		    mListButton.setEnabled(false);

		} else  { /* RUNNING */            // Stop the tracker
			stopTrackerService();
			//mSaveButton.setText("Save");
			mListButton.setClickable(true);
		    mListButton.setEnabled(true);
		}
		updateViewTrackingMode();
		break;
		
		// This button starts the TrackerSettings activity which lets the user
		//  change the tracker parameters on the fly. Changes are commnicated
		//  through shared preferences.
		case R.id.idTrackerSettingsButton:   
			String text = (String) mSettingsButton.getText();
			Log.d(TAG, "Text = " + text);
			if (text.equals("Settings")) {
				// Try to get the background service
				mBackgroundService = TrackerBackgroundService.getInstance();
				startActivity(new Intent(this, TrackerSettings.class));	
				
			} else if (text.equals("Sync")) {  // Text = "Sync" or "Register"
				// This is only reached by clicking on the Sync button in List View	
				mSettingsButton.setEnabled(false);
				mSettingsButton.setClickable(false);
				syncUnsyncedPoints();
			} else if (text.equals("Register")) {
				registerUnregisteredExpedition();
			}
			break;
			
		// The "list" button is used for various tasks, including listing,
		// and deleting tracks. The button's text and icon are changed depending on
		// the current state of the Activity.
		case R.id.idTrackerListButton:
			text = (String) mListButton.getText();
			if (text.equals("List")) {
				mState = TrackerSettings.VIEWING_MODE;
				spEditor.putInt(TrackerSettings.TRACKER_STATE_PREFERENCE, TrackerSettings.VIEWING_MODE);
				spEditor.commit();
				Intent intent = new Intent(this, TrackerListActivity.class); // List tracks
				startActivityForResult(intent, GET_EXPEDITION_ROW_ID);
			} else { 						// Delete this track
				deleteExpedition();
				finish();
			}
			break;
		}
	}

Problems/Known issues

For New Developers

Personal tools
NSF K-12