List of usage examples for android.content ContentResolver update
public final int update(@RequiresPermission.Write @NonNull Uri uri, @Nullable ContentValues values, @Nullable String where, @Nullable String[] selectionArgs)
From source file:com.akop.bach.parser.XboxLiveParser.java
private void parseGames(XboxLiveAccount account) throws ParserException, IOException { long started = System.currentTimeMillis(); String url = String.format(URL_GAME_LIST, mLocale); String page = getResponse(url); if (App.getConfig().logToConsole()) started = displayTimeTaken("Game page fetch", started); long accountId = account.getId(); String[] queryParams = new String[1]; int rowNo = 0; boolean changed = false; Cursor c;/*from w ww . j a v a 2s.com*/ ContentValues cv; long updated = System.currentTimeMillis(); List<ContentValues> newCvs = new ArrayList<ContentValues>(100); ContentResolver cr = mContext.getContentResolver(); List<String> gameIds = new ArrayList<String>(50); Matcher m = PATTERN_GAME_ITEM.matcher(page); while (m.find()) { String content = m.group(1); App.logv(" *** found it: " + content); Matcher im = PATTERN_GAME_TITLE_ID.matcher(content); if (!im.find()) continue; String uid = im.group(1); String title = htmlDecode(im.group(2)); String boxArtUrl = null; int gpAcquired = 0; int achUnlocked = 0; gameIds.add(uid); im = PATTERN_GAME_BOX_ART.matcher(content); if (im.find()) boxArtUrl = im.group(1); im = PATTERN_GAME_SCORE.matcher(content); if (im.find()) { try { gpAcquired = Integer.parseInt(im.group(1)); } catch (NumberFormatException e) { } } im = PATTERN_GAME_ACHIEVEMENTS.matcher(content); if (im.find()) { try { achUnlocked = Integer.parseInt(im.group(1)); } catch (NumberFormatException e) { } } // Check to see if we already have a record of this game queryParams[0] = uid; c = cr.query(Games.CONTENT_URI, GAMES_PROJECTION, Games.ACCOUNT_ID + "=" + accountId + " AND " + Games.UID + "=?", queryParams, null); try { if (c == null || !c.moveToFirst()) // New game { cv = new ContentValues(15); cv.put(Games.ACCOUNT_ID, accountId); cv.put(Games.TITLE, title); cv.put(Games.UID, uid); cv.put(Games.BOXART_URL, boxArtUrl); cv.put(Games.LAST_PLAYED, 0); cv.put(Games.LAST_UPDATED, updated); cv.put(Games.ACHIEVEMENTS_UNLOCKED, achUnlocked); cv.put(Games.ACHIEVEMENTS_TOTAL, achUnlocked); cv.put(Games.POINTS_ACQUIRED, gpAcquired); cv.put(Games.POINTS_TOTAL, gpAcquired); cv.put(Games.GAME_URL, (String) null); cv.put(Games.INDEX, rowNo); // Games with no achievements do not need achievement refresh cv.put(Games.ACHIEVEMENTS_STATUS, 1); newCvs.add(cv); } else // Existing game { long gameId = c.getLong(COLUMN_GAME_ID); long lastPlayedTicksRec = c.getLong(COLUMN_GAME_LAST_PLAYED_DATE); cv = new ContentValues(15); boolean refreshAchievements = true; if (refreshAchievements) { cv.put(Games.ACHIEVEMENTS_UNLOCKED, achUnlocked); cv.put(Games.ACHIEVEMENTS_TOTAL, achUnlocked); cv.put(Games.POINTS_ACQUIRED, gpAcquired); cv.put(Games.POINTS_TOTAL, gpAcquired); cv.put(Games.ACHIEVEMENTS_STATUS, 1); } cv.put(Games.BEACON_SET, 0); cv.put(Games.BEACON_TEXT, (String) null); cv.put(Games.LAST_PLAYED, 0); cv.put(Games.INDEX, rowNo); cv.put(Games.LAST_UPDATED, updated); cr.update(Games.CONTENT_URI, cv, Games._ID + "=" + gameId, null); changed = true; } } finally { if (c != null) c.close(); } rowNo++; } // Remove games that are no longer present c = cr.query(Games.CONTENT_URI, GAMES_PROJECTION, Games.ACCOUNT_ID + "=" + accountId, null, null); if (c != null) { while (c.moveToNext()) { if (!gameIds.contains(c.getString(COLUMN_GAME_UID))) { // Game is no longer in list of played games; remove it cr.delete(ContentUris.withAppendedId(Games.CONTENT_URI, c.getLong(COLUMN_GAME_ID)), null, null); changed = true; } } c.close(); } if (App.getConfig().logToConsole()) started = displayTimeTaken("Game page processing", started); if (newCvs.size() > 0) { changed = true; ContentValues[] cvs = new ContentValues[newCvs.size()]; newCvs.toArray(cvs); cr.bulkInsert(Games.CONTENT_URI, cvs); if (App.getConfig().logToConsole()) displayTimeTaken("Game page insertion", started); } account.refresh(Preferences.get(mContext)); account.setLastGameUpdate(System.currentTimeMillis()); account.save(Preferences.get(mContext)); if (changed) cr.notifyChange(Games.CONTENT_URI, null); }
From source file:com.akop.bach.parser.PsnUsParser.java
protected void parseGames(PsnAccount account) throws ParserException, IOException { String page = getResponse(String.format(URL_GAMES, URLEncoder.encode(account.getScreenName(), "UTF-8")), true);//from w w w .jav a 2s . c o m ContentResolver cr = mContext.getContentResolver(); boolean changed = false; long updated = System.currentTimeMillis(); Cursor c; String title; String iconUrl; String uid; int progress; int bronze; int silver; int gold; int platinum; String[] queryParams = new String[1]; final long accountId = account.getId(); ContentValues cv; List<ContentValues> newCvs = new ArrayList<ContentValues>(100); long started = System.currentTimeMillis(); Matcher m; Matcher gameMatcher = PATTERN_GAMES.matcher(page); for (int rowNo = 1; gameMatcher.find(); rowNo++) { String group = gameMatcher.group(1); if (!(m = PATTERN_GAME_UID.matcher(group)).find()) continue; uid = m.group(2); progress = 0; if ((m = PATTERN_GAME_PROGRESS.matcher(group)).find()) progress = Integer.parseInt(m.group(1)); bronze = silver = gold = platinum = 0; if ((m = PATTERN_GAME_TROPHIES.matcher(group)).find()) { bronze = Integer.parseInt(m.group(1)); if (m.find()) { silver = Integer.parseInt(m.group(1)); if (m.find()) { gold = Integer.parseInt(m.group(1)); if (m.find()) { platinum = Integer.parseInt(m.group(1)); } } } } // Check to see if we already have a record of this game queryParams[0] = uid; c = cr.query(Games.CONTENT_URI, GAMES_PROJECTION, Games.ACCOUNT_ID + "=" + accountId + " AND " + Games.UID + "=?", queryParams, null); changed = true; try { if (c == null || !c.moveToFirst()) // New game { title = ""; if ((m = PATTERN_GAME_TITLE.matcher(group)).find()) title = htmlDecode(m.group(1)); iconUrl = null; if ((m = PATTERN_GAME_ICON.matcher(group)).find()) iconUrl = getAvatarImage(m.group(1)); cv = new ContentValues(15); cv.put(Games.ACCOUNT_ID, accountId); cv.put(Games.TITLE, title); cv.put(Games.UID, uid); cv.put(Games.ICON_URL, iconUrl); cv.put(Games.PROGRESS, progress); cv.put(Games.SORT_ORDER, rowNo); cv.put(Games.UNLOCKED_PLATINUM, platinum); cv.put(Games.UNLOCKED_GOLD, gold); cv.put(Games.UNLOCKED_SILVER, silver); cv.put(Games.UNLOCKED_BRONZE, bronze); cv.put(Games.TROPHIES_DIRTY, 1); cv.put(Games.LAST_UPDATED, updated); newCvs.add(cv); } else // Existing game { boolean isDirty = false; long gameId = c.getLong(COLUMN_GAME_ID); cv = new ContentValues(15); if (c.getInt(COLUMN_GAME_PROGRESS) != progress) { isDirty = true; cv.put(Games.PROGRESS, progress); } if (c.getInt(COLUMN_GAME_BRONZE) != bronze) { isDirty = true; cv.put(Games.UNLOCKED_BRONZE, bronze); } if (c.getInt(COLUMN_GAME_SILVER) != silver) { isDirty = true; cv.put(Games.UNLOCKED_SILVER, silver); } if (c.getInt(COLUMN_GAME_GOLD) != gold) { isDirty = true; cv.put(Games.UNLOCKED_GOLD, gold); } if (c.getInt(COLUMN_GAME_PLATINUM) != platinum) { isDirty = true; cv.put(Games.UNLOCKED_PLATINUM, platinum); } if (isDirty) cv.put(Games.TROPHIES_DIRTY, 1); cv.put(Games.SORT_ORDER, rowNo); cv.put(Games.LAST_UPDATED, updated); cr.update(Games.CONTENT_URI, cv, Games._ID + "=" + gameId, null); } } finally { if (c != null) c.close(); } } if (App.getConfig().logToConsole()) started = displayTimeTaken("Game page processing", started); if (newCvs.size() > 0) { changed = true; ContentValues[] cvs = new ContentValues[newCvs.size()]; newCvs.toArray(cvs); cr.bulkInsert(Games.CONTENT_URI, cvs); if (App.getConfig().logToConsole()) displayTimeTaken("Game page insertion", started); } account.refresh(Preferences.get(mContext)); account.setLastGameUpdate(System.currentTimeMillis()); account.save(Preferences.get(mContext)); if (changed) cr.notifyChange(Games.CONTENT_URI, null); }
From source file:de.ub0r.android.callmeter.data.RuleMatcher.java
/** * Match all unmatched logs./*from ww w.ja v a 2s. c o m*/ * * @param context {@link Context} * @param showStatus post status to dialog/handler * @return true if a log was matched */ static synchronized boolean match(final Context context, final boolean showStatus) { Log.d(TAG, "match(ctx, ", showStatus, ")"); long start = System.currentTimeMillis(); boolean ret = false; load(context); final ContentResolver cr = context.getContentResolver(); final Cursor cursor = cr.query(DataProvider.Logs.CONTENT_URI, DataProvider.Logs.PROJECTION, DataProvider.Logs.PLAN_ID + " = " + DataProvider.NO_ID, null, DataProvider.Logs.DATE + " ASC"); if (cursor != null && cursor.moveToFirst()) { final int l = cursor.getCount(); Handler h; if (showStatus) { h = Plans.getHandler(); if (h != null) { final Message m = h.obtainMessage(Plans.MSG_BACKGROUND_PROGRESS_MATCHER); m.arg1 = 0; m.arg2 = l; m.sendToTarget(); } } try { ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); int i = 1; do { ret |= matchLog(cr, ops, cursor); if (i % PROGRESS_STEPS == 0 || (i < PROGRESS_STEPS && i % CallMeter.TEN == 0)) { h = Plans.getHandler(); if (h != null) { final Message m = h.obtainMessage(Plans.MSG_BACKGROUND_PROGRESS_MATCHER); m.arg1 = i; m.arg2 = l; Log.d(TAG, "send progress: ", i, "/", l); m.sendToTarget(); } else { Log.d(TAG, "send progress: ", i, " handler=null"); } Log.d(TAG, "save logs.."); cr.applyBatch(DataProvider.AUTHORITY, ops); ops.clear(); Log.d(TAG, "sleeping.."); try { Thread.sleep(CallMeter.MILLIS); } catch (InterruptedException e) { Log.e(TAG, "sleep interrupted", e); } Log.d(TAG, "sleep finished"); } ++i; } while (cursor.moveToNext()); if (ops.size() > 0) { cr.applyBatch(DataProvider.AUTHORITY, ops); } } catch (IllegalStateException e) { Log.e(TAG, "illegal state in RuleMatcher's loop", e); } catch (OperationApplicationException e) { Log.e(TAG, "illegal operation in RuleMatcher's loop", e); } catch (RemoteException e) { Log.e(TAG, "remote exception in RuleMatcher's loop", e); } } try { if (cursor != null && !cursor.isClosed()) { cursor.close(); } } catch (IllegalStateException e) { Log.e(TAG, "illegal state while closing cursor", e); } if (ret) { final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context); final boolean a80 = p.getBoolean(Preferences.PREFS_ALERT80, true); final boolean a100 = p.getBoolean(Preferences.PREFS_ALERT100, true); // check for alerts if ((a80 || a100) && plans != null && plans.size() > 0) { final long now = System.currentTimeMillis(); int alert = 0; Plan alertPlan = null; int l = plans.size(); for (int i = 0; i < l; i++) { final Plan plan = plans.valueAt(i); if (plan == null) { continue; } if (plan.nextAlert > now) { Log.d(TAG, "%s: skip alert until: %d now=%d", plan, plan.nextAlert, now); continue; } int used = DataProvider.Plans.getUsed(plan.type, plan.limitType, plan.billedAmount, plan.billedCost); int usedRate = plan.limit > 0 ? (int) ((used * CallMeter.HUNDRED) / plan.limit) : 0; if (a100 && usedRate >= CallMeter.HUNDRED) { alert = usedRate; alertPlan = plan; } else if (a80 && alert < CallMeter.EIGHTY && usedRate >= CallMeter.EIGHTY) { alert = usedRate; alertPlan = plan; } } if (alert > 0) { final NotificationManager mNotificationMgr = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); final String t = String.format(context.getString(R.string.alerts_message), alertPlan.name, alert); NotificationCompat.Builder b = new NotificationCompat.Builder(context); b.setSmallIcon(android.R.drawable.stat_notify_error); b.setTicker(t); b.setWhen(now); b.setContentTitle(context.getString(R.string.alerts_title)); b.setContentText(t); Intent i = new Intent(context, Plans.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); b.setContentIntent(PendingIntent.getActivity(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT)); mNotificationMgr.notify(0, b.build()); // set nextAlert to beginning of next day Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, 1); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); alertPlan.nextAlert = cal.getTimeInMillis(); final ContentValues cv = new ContentValues(); cv.put(DataProvider.Plans.NEXT_ALERT, alertPlan.nextAlert); cr.update(DataProvider.Plans.CONTENT_URI, cv, DataProvider.Plans.ID + " = ?", new String[] { String.valueOf(alertPlan.id) }); } } } long end = System.currentTimeMillis(); Log.i(TAG, "match(): ", end - start, "ms"); return ret; }
From source file:com.akop.bach.parser.XboxLiveParser.java
private void parseAchievements(XboxLiveAccount account, long gameId) throws ParserException, IOException { // Find game record in local DB ContentResolver cr = mContext.getContentResolver(); String gameUid = Games.getUid(mContext, gameId); long updated = System.currentTimeMillis(); long started = System.currentTimeMillis(); String pageUrl = String.format(URL_ACHIEVEMENTS, mLocale, gameUid); String page = getResponse(pageUrl); if (App.getConfig().logToConsole()) started = displayTimeTaken("Achievement page fetch", started); Matcher m;/* ww w . j a va 2s. co m*/ if (!(m = PATTERN_ACH_JSON.matcher(page)).find()) throw new ParserException(mContext, R.string.error_achieves_retrieval); JSONObject data = getJSONObject(m.group(1), false); JSONArray players = data.optJSONArray("Players"); if (players.length() < 1) throw new ParserException(mContext, R.string.error_achieves_retrieval); JSONObject player = players.optJSONObject(0); String gamertag = player.optString("Gamertag"); List<ContentValues> cvList = new ArrayList<ContentValues>(100); JSONArray achieves = data.optJSONArray("Achievements"); for (int i = 0, n = achieves.length(); i < n; i++) { JSONObject achieve = achieves.optJSONObject(i); if (achieve == null || achieve.optString("Id") == null) continue; JSONObject progRoot = achieve.optJSONObject("EarnDates"); if (progRoot == null) continue; JSONObject prog = progRoot.optJSONObject(gamertag); String title; String description; String tileUrl; if (achieve.optBoolean("IsHidden")) { title = mContext.getString(R.string.secret_achieve_title); description = mContext.getString(R.string.secret_achieve_desc); tileUrl = URL_SECRET_ACHIEVE_TILE; } else { title = achieve.optString("Name"); description = achieve.optString("Description"); tileUrl = achieve.optString("TileUrl"); } ContentValues cv = new ContentValues(10); // TODO cv.put(Achievements.UID, achieve.optString("Id")); cv.put(Achievements.GAME_ID, gameId); cv.put(Achievements.TITLE, title); cv.put(Achievements.DESCRIPTION, description); cv.put(Achievements.ICON_URL, tileUrl); cv.put(Achievements.POINTS, achieve.optInt("Score", 0)); if (prog != null) { // Unlocked long earnedOn = 0; if (!prog.optBoolean("IsOffline")) earnedOn = parseTicks(prog.optString("EarnedOn")); cv.put(Achievements.ACQUIRED, earnedOn); cv.put(Achievements.LOCKED, 0); } else { // Locked cv.put(Achievements.ACQUIRED, 0); cv.put(Achievements.LOCKED, 1); } cvList.add(cv); } if (App.getConfig().logToConsole()) started = displayTimeTaken("New achievement parsing", started); ContentValues[] cva = new ContentValues[cvList.size()]; cvList.toArray(cva); cr.delete(Achievements.CONTENT_URI, Achievements.GAME_ID + "=" + gameId, null); // Bulk-insert new achievements cr.bulkInsert(Achievements.CONTENT_URI, cva); if (App.getConfig().logToConsole()) started = displayTimeTaken("New achievement processing", started); // Update game stats JSONObject game = data.optJSONObject("Game"); if (game != null) { ContentValues cv = new ContentValues(10); cv.put(Games.LAST_UPDATED, updated); cv.put(Games.ACHIEVEMENTS_STATUS, 0); cv.put(Games.ACHIEVEMENTS_TOTAL, game.optInt("PossibleAchievements", 0)); cv.put(Games.POINTS_TOTAL, game.optInt("PossibleScore", 0)); JSONObject progRoot = game.optJSONObject("Progress"); if (progRoot != null) { JSONObject progress = game.optJSONObject(gamertag); if (progress != null) { cv.put(Games.ACHIEVEMENTS_UNLOCKED, progress.optInt("Achievements", 0)); cv.put(Games.POINTS_ACQUIRED, progress.optInt("Score", 0)); cv.put(Games.LAST_PLAYED, parseTicks(progress.optString("LastPlayed"))); } } // Write changes cr.update(Games.CONTENT_URI, cv, Games._ID + "=" + gameId, null); } cr.notifyChange(Achievements.CONTENT_URI, null); if (App.getConfig().logToConsole()) displayTimeTaken("Updating Game", started); }
From source file:com.android.calendar.alerts.AlertService.java
/** * Processes the query results and bucketizes the alerts. * * @param highPriorityEvents This will contain future events, and concurrent events * that started recently (less than the interval DEPRIORITIZE_GRACE_PERIOD_MS). * @param mediumPriorityEvents This will contain concurrent events that started * more than DEPRIORITIZE_GRACE_PERIOD_MS ago. * @param lowPriorityEvents Will contain events that have ended. * @return Returns the number of new alerts to fire. If this is 0, it implies * a quiet update.//w w w. j a v a2 s . c o m */ static int processQuery(final Cursor alertCursor, final Context context, final long currentTime, ArrayList<NotificationInfo> highPriorityEvents, ArrayList<NotificationInfo> mediumPriorityEvents, ArrayList<NotificationInfo> lowPriorityEvents) { // Experimental reminder setting to only remind for events that have // been responded to with "yes" or "maybe". String skipRemindersPref = Utils.getSharedPreference(context, OtherPreferences.KEY_OTHER_REMINDERS_RESPONDED, ""); // Skip no-response events if the "Skip Reminders" preference has the second option, // "If declined or not responded", is selected. // Note that by default, the first option will be selected, so this will be false. boolean remindRespondedOnly = skipRemindersPref .equals(context.getResources().getStringArray(R.array.preferences_skip_reminders_values)[1]); // Experimental reminder setting to silence reminders when they are // during the pre-defined quiet hours. boolean useQuietHours = Utils.getSharedPreference(context, OtherPreferences.KEY_OTHER_QUIET_HOURS, false); // Note that the start time may be either before or after the end time, // depending on whether quiet hours cross through midnight. int quietHoursStartHour = OtherPreferences.QUIET_HOURS_DEFAULT_START_HOUR; int quietHoursStartMinute = OtherPreferences.QUIET_HOURS_DEFAULT_START_MINUTE; int quietHoursEndHour = OtherPreferences.QUIET_HOURS_DEFAULT_END_HOUR; int quietHoursEndMinute = OtherPreferences.QUIET_HOURS_DEFAULT_END_MINUTE; if (useQuietHours) { quietHoursStartHour = Utils.getSharedPreference(context, OtherPreferences.KEY_OTHER_QUIET_HOURS_START_HOUR, OtherPreferences.QUIET_HOURS_DEFAULT_START_HOUR); quietHoursStartMinute = Utils.getSharedPreference(context, OtherPreferences.KEY_OTHER_QUIET_HOURS_START_MINUTE, OtherPreferences.QUIET_HOURS_DEFAULT_START_MINUTE); quietHoursEndHour = Utils.getSharedPreference(context, OtherPreferences.KEY_OTHER_QUIET_HOURS_END_HOUR, OtherPreferences.QUIET_HOURS_DEFAULT_END_HOUR); quietHoursEndMinute = Utils.getSharedPreference(context, OtherPreferences.KEY_OTHER_QUIET_HOURS_END_MINUTE, OtherPreferences.QUIET_HOURS_DEFAULT_END_MINUTE); } Time time = new Time(); ContentResolver cr = context.getContentResolver(); HashMap<Long, NotificationInfo> eventIds = new HashMap<Long, NotificationInfo>(); int numFired = 0; try { while (alertCursor.moveToNext()) { final long alertId = alertCursor.getLong(ALERT_INDEX_ID); final long eventId = alertCursor.getLong(ALERT_INDEX_EVENT_ID); final int minutes = alertCursor.getInt(ALERT_INDEX_MINUTES); final String eventName = alertCursor.getString(ALERT_INDEX_TITLE); final String description = alertCursor.getString(ALERT_INDEX_DESCRIPTION); final String location = alertCursor.getString(ALERT_INDEX_EVENT_LOCATION); final int status = alertCursor.getInt(ALERT_INDEX_SELF_ATTENDEE_STATUS); final boolean declined = status == Attendees.ATTENDEE_STATUS_DECLINED; final boolean responded = status != Attendees.ATTENDEE_STATUS_NONE && status != Attendees.ATTENDEE_STATUS_INVITED; final long beginTime = alertCursor.getLong(ALERT_INDEX_BEGIN); final long endTime = alertCursor.getLong(ALERT_INDEX_END); final Uri alertUri = ContentUris.withAppendedId(CalendarAlerts.CONTENT_URI, alertId); final long alarmTime = alertCursor.getLong(ALERT_INDEX_ALARM_TIME); boolean forceQuiet = false; if (useQuietHours) { // Quiet hours have been set. time.set(alarmTime); // Check whether the alarm will fire after the quiet hours // start time and/or before the quiet hours end time. boolean alarmAfterQuietHoursStart = (time.hour > quietHoursStartHour || (time.hour == quietHoursStartHour && time.minute >= quietHoursStartMinute)); boolean alarmBeforeQuietHoursEnd = (time.hour < quietHoursEndHour || (time.hour == quietHoursEndHour && time.minute <= quietHoursEndMinute)); // Check if quiet hours crosses through midnight, iff: // start hour is after end hour, or // start hour is equal to end hour, and start minute is // after end minute. // i.e. 22:30 - 06:45; 12:45 - 12:00 // 01:05 - 10:30; 05:00 - 05:30 boolean quietHoursCrossesMidnight = quietHoursStartHour > quietHoursEndHour || (quietHoursStartHour == quietHoursEndHour && quietHoursStartMinute > quietHoursEndMinute); if (quietHoursCrossesMidnight) { // Quiet hours crosses midnight. Alarm should be quiet // if it's after start time OR before end time. if (alarmAfterQuietHoursStart || alarmBeforeQuietHoursEnd) { forceQuiet = true; } } else { // Quiet hours doesn't cross midnight. Alarm should be // quiet if it's after start time AND before end time. if (alarmAfterQuietHoursStart && alarmBeforeQuietHoursEnd) { forceQuiet = true; } } } int state = alertCursor.getInt(ALERT_INDEX_STATE); final boolean allDay = alertCursor.getInt(ALERT_INDEX_ALL_DAY) != 0; // Use app local storage to keep track of fired alerts to fix problem of multiple // installed calendar apps potentially causing missed alarms. boolean newAlertOverride = false; if (AlertUtils.BYPASS_DB && ((currentTime - alarmTime) / MINUTE_MS < 1)) { // To avoid re-firing alerts, only fire if alarmTime is very recent. Otherwise // we can get refires for non-dismissed alerts after app installation, or if the // SharedPrefs was cleared too early. This means alerts that were timed while // the phone was off may show up silently in the notification bar. boolean alreadyFired = AlertUtils.hasAlertFiredInSharedPrefs(context, eventId, beginTime, alarmTime); if (!alreadyFired) { newAlertOverride = true; } } if (DEBUG) { StringBuilder msgBuilder = new StringBuilder(); msgBuilder.append("alertCursor result: alarmTime:").append(alarmTime).append(" alertId:") .append(alertId).append(" eventId:").append(eventId).append(" state: ").append(state) .append(" minutes:").append(minutes).append(" declined:").append(declined) .append(" responded:").append(responded).append(" beginTime:").append(beginTime) .append(" endTime:").append(endTime).append(" allDay:").append(allDay) .append(" alarmTime:").append(alarmTime).append(" forceQuiet:").append(forceQuiet); if (AlertUtils.BYPASS_DB) { msgBuilder.append(" newAlertOverride: " + newAlertOverride); } Log.d(TAG, msgBuilder.toString()); } ContentValues values = new ContentValues(); int newState = -1; boolean newAlert = false; // Uncomment for the behavior of clearing out alerts after the // events ended. b/1880369 // // if (endTime < currentTime) { // newState = CalendarAlerts.DISMISSED; // } else // Remove declined events boolean sendAlert = !declined; // Check for experimental reminder settings. if (remindRespondedOnly) { // If the experimental setting is turned on, then only send // the alert if you've responded to the event. sendAlert = sendAlert && responded; } if (sendAlert) { if (state == CalendarAlerts.STATE_SCHEDULED || newAlertOverride) { newState = CalendarAlerts.STATE_FIRED; numFired++; // If quiet hours are forcing the alarm to be silent, // keep newAlert as false so it will not make noise. if (!forceQuiet) { newAlert = true; } // Record the received time in the CalendarAlerts table. // This is useful for finding bugs that cause alarms to be // missed or delayed. values.put(CalendarAlerts.RECEIVED_TIME, currentTime); } } else { newState = CalendarAlerts.STATE_DISMISSED; } // Update row if state changed if (newState != -1) { values.put(CalendarAlerts.STATE, newState); state = newState; if (AlertUtils.BYPASS_DB) { AlertUtils.setAlertFiredInSharedPrefs(context, eventId, beginTime, alarmTime); } } if (state == CalendarAlerts.STATE_FIRED) { // Record the time posting to notification manager. // This is used for debugging missed alarms. values.put(CalendarAlerts.NOTIFY_TIME, currentTime); } // Write row to if anything changed if (values.size() > 0) cr.update(alertUri, values, null, null); if (state != CalendarAlerts.STATE_FIRED) { continue; } // TODO: Prefer accepted events in case of ties. NotificationInfo newInfo = new NotificationInfo(eventName, location, description, beginTime, endTime, eventId, allDay, newAlert); // Adjust for all day events to ensure the right bucket. Don't use the 1/4 event // duration grace period for these. long beginTimeAdjustedForAllDay = beginTime; String tz = null; if (allDay) { tz = TimeZone.getDefault().getID(); beginTimeAdjustedForAllDay = Utils.convertAlldayUtcToLocal(null, beginTime, tz); } // Handle multiple alerts for the same event ID. if (eventIds.containsKey(eventId)) { NotificationInfo oldInfo = eventIds.get(eventId); long oldBeginTimeAdjustedForAllDay = oldInfo.startMillis; if (allDay) { oldBeginTimeAdjustedForAllDay = Utils.convertAlldayUtcToLocal(null, oldInfo.startMillis, tz); } // Determine whether to replace the previous reminder with this one. // Query results are sorted so this one will always have a lower start time. long oldStartInterval = oldBeginTimeAdjustedForAllDay - currentTime; long newStartInterval = beginTimeAdjustedForAllDay - currentTime; boolean dropOld; if (newStartInterval < 0 && oldStartInterval > 0) { // Use this reminder if this event started recently dropOld = Math.abs(newStartInterval) < MIN_DEPRIORITIZE_GRACE_PERIOD_MS; } else { // ... or if this one has a closer start time. dropOld = Math.abs(newStartInterval) < Math.abs(oldStartInterval); } if (dropOld) { // This is a recurring event that has a more relevant start time, // drop other reminder in favor of this one. // // It will only be present in 1 of these buckets; just remove from // multiple buckets since this occurrence is rare enough that the // inefficiency of multiple removals shouldn't be a big deal to // justify a more complicated data structure. Expired events don't // have individual notifications so we don't need to clean that up. highPriorityEvents.remove(oldInfo); mediumPriorityEvents.remove(oldInfo); if (DEBUG) { Log.d(TAG, "Dropping alert for recurring event ID:" + oldInfo.eventId + ", startTime:" + oldInfo.startMillis + " in favor of startTime:" + newInfo.startMillis); } } else { // Skip duplicate reminders for the same event instance. continue; } } // TODO: Prioritize by "primary" calendar eventIds.put(eventId, newInfo); long highPriorityCutoff = currentTime - getGracePeriodMs(beginTime, endTime, allDay); if (beginTimeAdjustedForAllDay > highPriorityCutoff) { // High priority = future events or events that just started highPriorityEvents.add(newInfo); } else if (allDay && tz != null && DateUtils.isToday(beginTimeAdjustedForAllDay)) { // Medium priority = in progress all day events mediumPriorityEvents.add(newInfo); } else { lowPriorityEvents.add(newInfo); } } // TODO(cwren) add beginTime/startTime GlobalDismissManager.processEventIds(context, eventIds.keySet()); } finally { if (alertCursor != null) { alertCursor.close(); } } return numFired; }
From source file:gov.wa.wsdot.android.wsdot.service.MountainPassesSyncService.java
@Override protected void onHandleIntent(Intent intent) { ContentResolver resolver = getContentResolver(); Cursor cursor = null;// ww w.j a v a 2 s . c om long now = System.currentTimeMillis(); boolean shouldUpdate = true; String responseString = ""; /** * Check the cache table for the last time data was downloaded. If we are within * the allowed time period, don't sync, otherwise get fresh data from the server. */ try { cursor = resolver.query(Caches.CONTENT_URI, new String[] { Caches.CACHE_LAST_UPDATED }, Caches.CACHE_TABLE_NAME + " LIKE ?", new String[] { "mountain_passes" }, null); if (cursor != null && cursor.moveToFirst()) { long lastUpdated = cursor.getLong(0); //long deltaMinutes = (now - lastUpdated) / DateUtils.MINUTE_IN_MILLIS; //Log.d(DEBUG_TAG, "Delta since last update is " + deltaMinutes + " min"); shouldUpdate = (Math.abs(now - lastUpdated) > (15 * DateUtils.MINUTE_IN_MILLIS)); } } finally { if (cursor != null) { cursor.close(); } } // Ability to force a refresh of camera data. boolean forceUpdate = intent.getBooleanExtra("forceUpdate", false); if (shouldUpdate || forceUpdate) { List<Integer> starred = new ArrayList<Integer>(); starred = getStarred(); buildWeatherPhrases(); try { URL url = new URL(MOUNTAIN_PASS_URL); URLConnection urlConn = url.openConnection(); BufferedInputStream bis = new BufferedInputStream(urlConn.getInputStream()); GZIPInputStream gzin = new GZIPInputStream(bis); InputStreamReader is = new InputStreamReader(gzin); BufferedReader in = new BufferedReader(is); String mDateUpdated = ""; String jsonFile = ""; String line; while ((line = in.readLine()) != null) jsonFile += line; in.close(); JSONObject obj = new JSONObject(jsonFile); JSONObject result = obj.getJSONObject("GetMountainPassConditionsResult"); JSONArray passConditions = result.getJSONArray("PassCondition"); String weatherCondition; Integer weather_image; Integer forecast_weather_image; List<ContentValues> passes = new ArrayList<ContentValues>(); int numConditions = passConditions.length(); for (int j = 0; j < numConditions; j++) { JSONObject pass = passConditions.getJSONObject(j); ContentValues passData = new ContentValues(); weatherCondition = pass.getString("WeatherCondition"); weather_image = getWeatherImage(weatherPhrases, weatherCondition); String tempDate = pass.getString("DateUpdated"); try { tempDate = tempDate.replace("[", ""); tempDate = tempDate.replace("]", ""); String[] a = tempDate.split(","); StringBuilder sb = new StringBuilder(); for (int m = 0; m < 5; m++) { sb.append(a[m]); sb.append(","); } tempDate = sb.toString().trim(); tempDate = tempDate.substring(0, tempDate.length() - 1); Date date = parseDateFormat.parse(tempDate); mDateUpdated = displayDateFormat.format(date); } catch (Exception e) { Log.e(DEBUG_TAG, "Error parsing date: " + tempDate, e); mDateUpdated = "N/A"; } JSONArray forecasts = pass.getJSONArray("Forecast"); JSONArray forecastItems = new JSONArray(); int numForecasts = forecasts.length(); for (int l = 0; l < numForecasts; l++) { JSONObject forecast = forecasts.getJSONObject(l); if (isNight(forecast.getString("Day"))) { forecast_weather_image = getWeatherImage(weatherPhrasesNight, forecast.getString("ForecastText")); } else { forecast_weather_image = getWeatherImage(weatherPhrases, forecast.getString("ForecastText")); } forecast.put("weather_icon", forecast_weather_image); if (l == 0) { if (weatherCondition.equals("")) { weatherCondition = forecast.getString("ForecastText").split("\\.")[0] + "."; weather_image = forecast_weather_image; } } forecastItems.put(forecast); } passData.put(MountainPasses.MOUNTAIN_PASS_ID, pass.getString("MountainPassId")); passData.put(MountainPasses.MOUNTAIN_PASS_NAME, pass.getString("MountainPassName")); passData.put(MountainPasses.MOUNTAIN_PASS_WEATHER_ICON, weather_image); passData.put(MountainPasses.MOUNTAIN_PASS_FORECAST, forecastItems.toString()); passData.put(MountainPasses.MOUNTAIN_PASS_WEATHER_CONDITION, weatherCondition); passData.put(MountainPasses.MOUNTAIN_PASS_DATE_UPDATED, mDateUpdated); passData.put(MountainPasses.MOUNTAIN_PASS_CAMERA, pass.getString("Cameras")); passData.put(MountainPasses.MOUNTAIN_PASS_ELEVATION, pass.getString("ElevationInFeet")); passData.put(MountainPasses.MOUNTAIN_PASS_TRAVEL_ADVISORY_ACTIVE, pass.getString("TravelAdvisoryActive")); passData.put(MountainPasses.MOUNTAIN_PASS_ROAD_CONDITION, pass.getString("RoadCondition")); passData.put(MountainPasses.MOUNTAIN_PASS_TEMPERATURE, pass.getString("TemperatureInFahrenheit")); JSONObject restrictionOne = pass.getJSONObject("RestrictionOne"); passData.put(MountainPasses.MOUNTAIN_PASS_RESTRICTION_ONE, restrictionOne.getString("RestrictionText")); passData.put(MountainPasses.MOUNTAIN_PASS_RESTRICTION_ONE_DIRECTION, restrictionOne.getString("TravelDirection")); JSONObject restrictionTwo = pass.getJSONObject("RestrictionTwo"); passData.put(MountainPasses.MOUNTAIN_PASS_RESTRICTION_TWO, restrictionTwo.getString("RestrictionText")); passData.put(MountainPasses.MOUNTAIN_PASS_RESTRICTION_TWO_DIRECTION, restrictionTwo.getString("TravelDirection")); if (starred.contains(Integer.parseInt(pass.getString("MountainPassId")))) { passData.put(MountainPasses.MOUNTAIN_PASS_IS_STARRED, 1); } passes.add(passData); } // Purge existing mountain passes covered by incoming data resolver.delete(MountainPasses.CONTENT_URI, null, null); // Bulk insert all the new mountain passes resolver.bulkInsert(MountainPasses.CONTENT_URI, passes.toArray(new ContentValues[passes.size()])); // Update the cache table with the time we did the update ContentValues values = new ContentValues(); values.put(Caches.CACHE_LAST_UPDATED, System.currentTimeMillis()); resolver.update(Caches.CONTENT_URI, values, Caches.CACHE_TABLE_NAME + "=?", new String[] { "mountain_passes" }); responseString = "OK"; } catch (Exception e) { Log.e(DEBUG_TAG, "Error: " + e.getMessage()); responseString = e.getMessage(); } } else { responseString = "NOP"; } Intent broadcastIntent = new Intent(); broadcastIntent.setAction("gov.wa.wsdot.android.wsdot.intent.action.MOUNTAIN_PASSES_RESPONSE"); broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); broadcastIntent.putExtra("responseString", responseString); sendBroadcast(broadcastIntent); }