Skip to content

Android Client Architecture

Bob Evans edited this page Oct 9, 2013 · 10 revisions

Overview of the Android App.

Introduction

The Android client for Paco is the most complex piece of this system because it was designed to run off-network for as long as necessary and to talk to the network when it came around. In addition, it can render feedback, and soon experiments, in embedded webviews to allow for more custom experiment definitions and more adaptive behavioral protocols.

Highlights:

  • Java Android app
  • Stores data in a content provider with full sql data model. This has gotten quite cumbersome to iterate. Moving to lightweight storage in content provider
  • Communicates to the server with https and json
  • Allows some visualization of the data
  • Allows customized feedback pages based on responses to experiments.
  • Schedules the next scheduled event only. Updates the next each time it wakes up to signal the current event

Details

App Lifecycle Overview

Paco starts as a simple application. The user authenticates their Google credentials and is allowed to Find Experiments. This involves either querying the server for their personal experiments (those published to them or created by them) or querying for public experiments (those published to all).

When it downloads an experiment definition at this stage, it gets a lightweight version of the experiment. If the user joins the experiment, the app downloads the full definition and stores it in the Experiment Content provider. It also records a JOIN event that will be sent to the server just like a standard response to let the researcher know that the user has joined.

If the experiment has a schedule-based signaling mechanism, then the app starts the BeeperService which will reset the scheduled hardware wakeup alarm to fire at the next most recent experiment signal. We set only one hardware alarm so as to make it easier to manage cleanup and reset after reboot, package update, timezone change, or joining/leaving of experiments.

The app does nothing else until it is woken up by the hardware wakeup alarm. It then does several tasks.

  1. It creates an Android Notification to alert the user to respond
  2. It records this notification in a datastore table to allow restoration after reboots
  3. It creates an alarm to timeout that notification according to its timeout parameter
  4. It queries all running experiments for the next nearest scheduled signal and sets an alarm for it

When the timeout alarm goes off, if the user has not responded, it cancels the notification and records a missed response event to indicate that the user did not reply.

If, instead, the user responds to the notification in time, by clicking, then

  1. It will take the user into the app to the ExperimentExecutor
  2. which will render the experiment inputs and await the users responses.

When the user responds and saves their response

  1. The app records the responses as an event.
  2. It cancels the notification.
  3. It notifies the SyncService that there is work to do to upload events to the server datastore.

The SyncService is responsible for uploading any recorded events that have not yet been uploaded. It is called whenever a system change occurs or when the user has responded to an experiment. System changes include network connected, reboot, package update, timezone change, and others.

  1. When woken, it checks if there is network.
  2. If there is it looks for any events that have not yet been uploaded.
  3. It batches them into small groups and tries to upload them to the server.
  4. The server responds with a json list of each event, in order as sent, with the status of that event and if there is an error, an error message for that event.
  5. For all of the successful events, the SyncService marks them as uploaded.
  6. It continues while there is network until it has uploaded all events.

Whenever an Experiment is asked for its next scheduled signal, it computes the schedule according to its schedule type. It may be a self report experiment, a triggered experiment, or a scheduled experiment. See the discussion of Signaling Mechanisms in the next section.

When an experiment is over (it has a fixed start and end date), it will not return next scheduled times.

If a user stops an experiment, the app will record an JOINED=false event and sent it to the server.

Signaling Mechanisms

A very important part of the system is the SignalingMechanisms that drives notifications to the user to respond.

Embedded Webview for Feedback and Experiment Rendering

The Feedback rendering currently uses an embedded webview into which we have injected a javascript interface for enabling custom displays based on the data collected in the previous sample. We are moving to use an embedded web view for custom html experiment execution.

Data Model

The data model currently uses the ContentProvider to store parts of experiments and the events as separate tables. This has created a migration nightmare at the speed with which we add features to the experiment definition. We are migrating to a model that mostly stores the experiment as json so as to facilitate more rapid change in the experiment definitions. This will also benefit us by allowing us to use json for parceling as well.

** Photo Input ** Paco supports an input item for a Photo. This prompts the user to either take a picture with the Camera, or to pick a photo from the Gallery app. Paco launches the Camera app using the Activity Intent for the Camera and waits for the result, which is the url on the sd card of the photo just taken. Paco creates a thumbnail of the image to show as feedback to the user on the experiment executor form. If the user picks a Gallery image, then we launch the Gallery app and wait for the url of the picture selected and act as for the Camera choice. When we upload photos, currently, we base64 encode them into the json event payload. The server stores them in the datastore as a blob.

We will move to using the ImageService or the Cloud service to allow us to serve images back for report generation.

** Location Input ** The location input will cause the LocationManager service to be turned on when the experiment is registered. The trick is that the location service should have gotten a signal by the time the user is ready to save their response.

** Process Polling for App Launch Triggering ** Check the Background Process Polling Page.

** Generalized Polling for Android ** This is future work. Check Generalized Polling for Android for the current design ideas.

Clone this wiki locally