package com.hacktoolkit.android.user; import java.util.Date; import com.facebook.Request; import com.facebook.Response; import com.facebook.model.GraphUser; import com.hacktoolkit.android.constants.TimeConstants; import com.hacktoolkit.android.maps.MapUtils; import com.parse.ParseFacebookUtils; import com.parse.ParseGeoPoint; import com.parse.ParseUser; /** * HTKUser * * Represents the user of this app, and acts as a wrapper for ParseUser * @author Hacktoolkit * */ public class HTKUser { public static HTKUser getCurrentUser() { ParseUser parseUser = ParseUser.getCurrentUser(); HTKUser user = getCurrentUser(parseUser); return user; } public static HTKUser getCurrentUser(ParseUser parseUser) { HTKUser user = new HTKUser(parseUser); return user; } public static void logout() { ParseUser.logOut(); } private ParseUser parseUser; public static final long LOCATION_UPDATE_THRESHOLD = 3 * TimeConstants.ONE_MINUTE_MILLIS; public static final int MOVEMENT_THRESHOLD_METERS = 25; public HTKUser(ParseUser parseUser) { this.parseUser = parseUser; } public boolean isAuthenticated() { boolean auth = false; if (parseUser != null) { auth = parseUser.isAuthenticated(); } return auth; } public String getName() { String firstName = parseUser.getString("firstName"); String lastName = parseUser.getString("lastName"); StringBuffer sb = new StringBuffer(); sb.append(firstName); if (firstName != null && !firstName.equals("")) { sb.append(" "); sb.append(lastName); } String name = sb.toString(); return name; } public void updateWithGraphUser() { Request.newMeRequest(ParseFacebookUtils.getSession(), new Request.GraphUserCallback() { @Override public void onCompleted(GraphUser user, Response response) { if (user != null) { String fbId = user.getId(); String firstName = user.getFirstName(); String lastName = user.getLastName(); String email = (String) user.getProperty("email"); parseUser.put("fbId", fbId); parseUser.put("firstName", firstName); parseUser.put("lastName", lastName); parseUser.put("email", email); parseUser.saveEventually(); } } }).executeAsync(); } /** * updateLocation * * @param latitude * @param longitude * @param forceUpdate whether we should force an update * @return true if location was updated, false otherwise */ public boolean updateLocation(double latitude, double longitude, boolean forceUpdate) { boolean updated = false; if (forceUpdate || shouldUpdateLocation(latitude, longitude)) { ParseGeoPoint geoPoint = new ParseGeoPoint(latitude, longitude); parseUser.put("location", geoPoint); parseUser.put("locationLastUpdatedAt", new Date()); parseUser.saveEventually(); updated = true; } return updated; } /** * * @param latitude * @param longitude * @return true if the user's location should be updated */ private boolean shouldUpdateLocation(double latitude, double longitude) { boolean shouldUpdate = isSignificantMovement(latitude, longitude) && hasLocationUpdateThresholdElapsed(); return shouldUpdate; } /** * Helps determine whether an update should happen * @param latitude * @param longitude * @return true if the new coordinates represent a significant movement */ private boolean isSignificantMovement(double newLatitude, double newLongitude) { double previousLatitude = parseUser.getDouble("latitude"); double previousLongitude = parseUser.getDouble("longitude"); boolean significantMovement = false; if (previousLatitude == 0 && previousLongitude == 0) { significantMovement = true; } else { double distanceKm = MapUtils.geographicalGreatCircleDistance(previousLatitude, previousLongitude, newLatitude, newLongitude); significantMovement = distanceKm / 1000 > MOVEMENT_THRESHOLD_METERS; } return significantMovement; } /** * Helps determine whether an update should happen * Essentially rate-limits the number of updates * @return true if LOCATION_UPDATE_THRESHOLD has elapsed */ private boolean hasLocationUpdateThresholdElapsed() { long sinceLastUpdate = 0; Date locationLastUpdatedAt = parseUser.getDate("locationLastUpdatedAt"); Date now = new Date(); boolean elapsed = false; if (locationLastUpdatedAt == null) { elapsed = true; sinceLastUpdate = 0; } else { sinceLastUpdate = now.getTime() - locationLastUpdatedAt.getTime(); if (sinceLastUpdate > LOCATION_UPDATE_THRESHOLD) { elapsed = true; } } return elapsed; } }