/******************************************************************************* * Copyright 2011 The Regents of the University of California * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.ohmage.triggers.types.location; import android.content.Context; import android.content.Intent; import android.database.Cursor; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.ohmage.R; import org.ohmage.logprobe.Log; import org.ohmage.triggers.base.TriggerBase; import org.ohmage.triggers.ui.TriggerListActivity; /* * The concrete instance of the location based triggers class. * * This class inherits TriggerBase and is registered with the * framework by adding an entry in TriggerTypeMap. This class * implements the abstract functions in TriggerBase through * which the framework interacts with location triggers. */ public class LocationTrigger extends TriggerBase { private static final String TAG = "LocationTrigger"; //This string must be unique across all trigger types //registered with the framework. private static final String TRIGGER_TYPE = "LocationTrigger"; private static final String KEY_PLACES = "places"; private static final String KEY_NAME = "name"; private static final String KEY_LOCATIONS = "locations"; private static final String KEY_LATITUDE = "latitude"; private static final String KEY_LONGITUDE = "longitude"; private static final String KEY_RADIUS = "radius"; /* IMPLEMENTATION OF THE ABSTRACT FUNCTIONS */ @Override public String getTriggerTypeDisplayName(Context context) { return context.getString(R.string.trigger_loc_display_name); } @Override public String getTriggerType() { return TRIGGER_TYPE; } @Override public boolean hasSettings() { return true; } @Override /* * The summary of a location trigger is the information * related to its time range. If there is no time range set, * returns "Always". If there is a time range, it returns * the range in the form "start - end". */ public String getDisplaySummary(Context context, String trigDesc) { LocTrigDesc desc = new LocTrigDesc(); if(!desc.loadString(trigDesc)) { return null; } String ret = ""; if(!desc.isRangeEnabled()) { ret = "Always"; } else { ret = desc.getStartTime().toString() + " - " + desc.getEndTime().toString(); } return ret; } @Override /* * The display title of a location trigger is the name * of the location. */ public String getDisplayTitle(Context context, String trigDesc) { LocTrigDesc desc = new LocTrigDesc(); if(!desc.loadString(trigDesc)) { return null; } return desc.getLocation(); } @Override public int getIcon() { return R.drawable.map; } @Override public void launchTriggerCreateActivity(Context context, final String campaignUrn, String [] actions, String[] preselectedActions, boolean adminMode) { //Register a listener with the editor //activity to listen for the 'done' event LocTrigEditActivity.setOnExitListener( new LocTrigEditActivity.ExitListener() { @Override public void onDone(Context context, int trigId, String trigDesc, String actDesc) { //When done, save the trigger to the db addNewTrigger(context, campaignUrn, trigDesc, actDesc); } }); Intent i = new Intent(context, LocTrigEditActivity.class); i.putExtra(LocTrigEditActivity.KEY_ADMIN_MODE, adminMode); i.putExtra(TriggerListActivity.KEY_ACTIONS, actions); if (preselectedActions != null) i.putExtra(TriggerListActivity.KEY_PRESELECTED_ACTIONS, preselectedActions); context.startActivity(i); } @Override public void launchSettingsEditActivity(Context context, boolean adminMode) { Intent i = new Intent(context, LocTrigSettingsActivity.class); i.putExtra(LocTrigSettingsActivity.KEY_ADMIN_MODE, adminMode); context.startActivity(i); } @Override public void resetSettings(Context context) { LocTrigDB.deleteDatabase(context); LocTrigTracingSettActivity.resetAllSettings(context); } @Override public void launchTriggerEditActivity(Context context, int trigId, String trigDesc, String actDesc, String[] mActions, boolean adminMode) { //Register a listener with the editor //activity to listen for the 'done' event LocTrigEditActivity.setOnExitListener( new LocTrigEditActivity.ExitListener() { @Override public void onDone(Context context, int trigId, String trigDesc, String actDesc) { //Update the trigger in db when done updateTrigger(context, trigId, trigDesc, actDesc); } }); //Pass the trigger details to the editor Intent i = new Intent(context, LocTrigEditActivity.class); i.putExtra(LocTrigEditActivity.KEY_TRIG_ID, trigId); i.putExtra(LocTrigEditActivity.KEY_TRIG_DESC, trigDesc); i.putExtra(LocTrigEditActivity.KEY_ACT_DESC, actDesc); i.putExtra(LocTrigEditActivity.KEY_ADMIN_MODE, adminMode); i.putExtra(TriggerListActivity.KEY_ACTIONS, mActions); context.startActivity(i); } @Override public void stopTrigger(Context context, int trigId, String trigDesc) { Log.v(TAG, "LocationTrigger: removeTrigger(" + trigId + ", " + trigDesc + ")"); //Tell the service to stop this trigger Intent i = new Intent(context, LocTrigService.class); i.setAction(LocTrigService.ACTION_REMOVE_TRIGGER); i.putExtra(LocTrigService.KEY_TRIG_ID, trigId); i.putExtra(LocTrigService.KEY_TRIG_DESC, trigDesc); context.startService(i); } @Override public void resetTrigger(Context context, int trigId, String trigDesc) { Log.v(TAG, "LocationTrigger: resetTrigger(" + trigId + ", " + trigDesc + ")"); //Tell the service to restart the trigger Intent i = new Intent(context, LocTrigService.class); i.setAction(LocTrigService.ACTION_RESET_TRIGGER); i.putExtra(LocTrigService.KEY_TRIG_ID, trigId); i.putExtra(LocTrigService.KEY_TRIG_DESC, trigDesc); context.startService(i); } @Override public void startTrigger(Context context, int trigId, String trigDesc) { Log.v(TAG, "LocationTrigger: startTrigger(" + trigId + ", " + trigDesc + ")"); //Tell the service to start the trigger Intent i = new Intent(context, LocTrigService.class); i.setAction(LocTrigService.ACTION_START_TRIGGER); i.putExtra(LocTrigService.KEY_TRIG_ID, trigId); i.putExtra(LocTrigService.KEY_TRIG_DESC, trigDesc); context.startService(i); } /* * Helper function to serialize all the location settings to * a JSON array. */ private JSONArray getLocations(Context context, int categId) { JSONArray jLocs = new JSONArray(); LocTrigDB db = new LocTrigDB(context); db.open(); Cursor cLocs = db.getLocations(categId); if(cLocs.moveToFirst()) { do { int lat = cLocs.getInt( cLocs.getColumnIndexOrThrow(LocTrigDB.KEY_LAT)); int lng = cLocs.getInt( cLocs.getColumnIndexOrThrow(LocTrigDB.KEY_LONG)); float radius = cLocs.getFloat( cLocs.getColumnIndexOrThrow(LocTrigDB.KEY_RADIUS)); JSONObject jLoc = new JSONObject(); try { jLoc.put(KEY_LATITUDE, (lat / 1E6)); jLoc.put(KEY_LONGITUDE, (lng / 1E6)); jLoc.put(KEY_RADIUS, radius); jLocs.put(jLoc); } catch (JSONException e) { Log.e(TAG, "LocationTrigger: Error adding locations to " + "preference JSON", e); } } while(cLocs.moveToNext()); } cLocs.close(); db.close(); return jLocs; } @Override /* * Returns a JSON object containing all the location * settings. */ public JSONObject getPreferences(Context context) { LocTrigDB db = new LocTrigDB(context); db.open(); JSONArray jPlaces = new JSONArray(); Cursor cCategs = db.getAllCategories(); if(cCategs.moveToFirst()) { do { String categName = cCategs.getString( cCategs.getColumnIndexOrThrow(LocTrigDB.KEY_NAME)); int categId = cCategs.getInt( cCategs.getColumnIndexOrThrow(LocTrigDB.KEY_ID)); JSONObject jPlace = new JSONObject(); try { jPlace.put(KEY_NAME, categName); jPlace.put(KEY_LOCATIONS, getLocations(context, categId)); jPlaces.put(jPlace); } catch (JSONException e) { Log.e(TAG, "LocationTrigger: Error adding place to " + "preference JSON", e); } } while(cCategs.moveToNext()); } cCategs.close(); db.close(); JSONObject jPref = new JSONObject(); try { jPref.put(KEY_PLACES, jPlaces); } catch (JSONException e) { Log.e(TAG, "LocationTrigger: Error adding places to " + "preference JSON", e); } return jPref; } }