@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.deviations_row); Log.d(TAG, "details!?"); /*Bundle extras = getIntent().getExtras(); Deviation deviation = extras.getParcelable(EXTRA_DEVIATION); if (extras.containsKey(EXTRA_DEVIATION_NOTIFICATION_ID)) { int notificationId = extras.getInt(EXTRA_DEVIATION_NOTIFICATION_ID); NotificationManager mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); mNotificationManager.cancel(notificationId); }*/ final Uri uri = getIntent().getData(); String header = uri.getQueryParameter("header"); String details = uri.getQueryParameter("details"); String scope = uri.getQueryParameter("scope"); String reference = uri.getQueryParameter("reference"); Time created = new Time(); created.parse3339(uri.getQueryParameter("created")); int notificationId = Integer.parseInt(uri.getQueryParameter("notificationId")); TextView headerView = (TextView) findViewById(R.id.deviation_header); headerView.setText(header); TextView detailsView = (TextView) findViewById(R.id.deviation_details); detailsView.setText(details); TextView createdView = (TextView) findViewById(R.id.deviation_created); createdView.setText(created.format("%F %R")); NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); mNotificationManager.cancel(notificationId); }
private long parse3339(String time) { if (time == null || time.length() == 0) { return 0; } if (timestamper != null) { try { timestamper.parse3339(time); } catch (TimeFormatException e) { parse_trace("got TimeFormatException parsing timestamp: \"" + time + '"'); e.printStackTrace(); return 0; } return timestamper.normalize(false); } else { Date timestamp = new Date(); SimpleDateFormat rfc3339 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); rfc3339.setLenient(true); try { timestamp = rfc3339.parse(time); } catch (ParseException e) { parse_trace("got ParseException parsing timestamp: \"" + time + '"'); e.printStackTrace(); return 0; } return timestamp.getTime(); } }
/** * Parse a NWS date string into a Unix timestamp. Assumes incoming values are in the format * "2009-03-23T18:00:00-07:00", which we adjust slightly to correctly follow RFC 3339 before * parsing. */ private static long parseDate(String raw) throws TimeFormatException { // Inject milliseconds so that NWS dates follow RFC sEditable.clear(); sEditable.append(raw); sEditable.insert(19, ".000"); String rfcFormat = sEditable.toString(); sTime.parse3339(rfcFormat); return sTime.toMillis(false); }
public static Time timeFrom3339(String s3339) { final android.text.format.Time time = new Time(); if (TextUtils.isEmpty(s3339)) { return time; } try { time.parse3339(s3339); } catch (TimeFormatException e) { return time; } time.switchTimezone(android.text.format.Time.getCurrentTimezone()); return time; }
/** * Clear out the map and stuff an Entry into it in a format that can be inserted into a content * provider. * * <p>If a date is before 1970 or past 2038, ENTRY_INVALID is returned, and DTSTART is set to -1. * This is due to the current 32-bit time restriction and will be fixed in a future release. * * @return ENTRY_OK, ENTRY_DELETED, or ENTRY_INVALID */ private int entryToContentValues( EventEntry event, Long syncLocalId, ContentValues map, Object info) { SyncInfo syncInfo = (SyncInfo) info; // There are 3 cases for parsing a date-time string: // // 1. The date-time string specifies a date and time with a time offset. // (The "normal" format.) // 2. The date-time string is just a date, used for all-day events, // with no time or time offset fields. (The "all-day" format.) // 3. The date-time string specifies a date and time, but no time // offset. (The "floating" format, not supported yet.) // // Case 1: Time.parse3339() converts the date-time string to UTC and // sets the Time.timezone to UTC. It does not matter what the initial // Time.timezone field was set to. The initial timezone is ignored. // // Case 2: The date-time string doesn't specify the time. // Time.parse3339() just sets the date but not the time (hour, minute, // second) fields. (The time fields should be zero, meaning midnight.) // This code then sets the timezone to UTC (because this is an all-day // event). It does not matter in this case either what the initial // Time.timezone field was set to. // // Case 3: This is a "floating time" (which we do not support yet). // In this case, it will matter what the initial Time.timezone is set // to. It should use UTC. If I specify a floating time of 1pm then I // want that event displayed at 1pm in every timezone. The easiest way // to support this would be store it as 1pm in UTC and mark the event // as "isFloating" (with a new database column). Then when displaying // the event, the code checks "isFloating" and just leaves the time at // 1pm without doing any conversion to the local timezone. // // So in all cases, it is correct to set the Time.timezone to UTC. Time time = new Time(Time.TIMEZONE_UTC); map.clear(); // Base sync info map.put(Events._SYNC_ID, event.getId()); String version = event.getEditUri(); if (!StringUtils.isEmpty(version)) { // Always rewrite the edit URL to https for dasher account to avoid // redirection. map.put(Events._SYNC_VERSION, rewriteUrlforAccount(getAccount(), version)); } // see if this is an exception to an existing event/recurrence. String originalId = event.getOriginalEventId(); String originalStartTime = event.getOriginalEventStartTime(); boolean isRecurrenceException = false; if (!StringUtils.isEmpty(originalId) && !StringUtils.isEmpty(originalStartTime)) { isRecurrenceException = true; time.parse3339(originalStartTime); map.put(Events.ORIGINAL_EVENT, originalId); map.put(Events.ORIGINAL_INSTANCE_TIME, time.toMillis(false /* use isDst */)); map.put(Events.ORIGINAL_ALL_DAY, time.allDay ? 1 : 0); } // Event status byte status = event.getStatus(); switch (status) { case EventEntry.STATUS_CANCELED: if (!isRecurrenceException) { return ENTRY_DELETED; } map.put(Events.STATUS, sCanceledStatus); break; case EventEntry.STATUS_TENTATIVE: map.put(Events.STATUS, sTentativeStatus); break; case EventEntry.STATUS_CONFIRMED: map.put(Events.STATUS, sConfirmedStatus); break; default: // should not happen return ENTRY_INVALID; } map.put(Events._SYNC_LOCAL_ID, syncLocalId); // Updated time, only needed for non-deleted items String updated = event.getUpdateDate(); map.put(Events._SYNC_TIME, updated); map.put(Events._SYNC_DIRTY, 0); // visibility switch (event.getVisibility()) { case EventEntry.VISIBILITY_DEFAULT: map.put(Events.VISIBILITY, Events.VISIBILITY_DEFAULT); break; case EventEntry.VISIBILITY_CONFIDENTIAL: map.put(Events.VISIBILITY, Events.VISIBILITY_CONFIDENTIAL); break; case EventEntry.VISIBILITY_PRIVATE: map.put(Events.VISIBILITY, Events.VISIBILITY_PRIVATE); break; case EventEntry.VISIBILITY_PUBLIC: map.put(Events.VISIBILITY, Events.VISIBILITY_PUBLIC); break; default: // should not happen Log.e(TAG, "Unexpected visibility " + event.getVisibility()); return ENTRY_INVALID; } // transparency switch (event.getTransparency()) { case EventEntry.TRANSPARENCY_OPAQUE: map.put(Events.TRANSPARENCY, Events.TRANSPARENCY_OPAQUE); break; case EventEntry.TRANSPARENCY_TRANSPARENT: map.put(Events.TRANSPARENCY, Events.TRANSPARENCY_TRANSPARENT); break; default: // should not happen Log.e(TAG, "Unexpected transparency " + event.getTransparency()); return ENTRY_INVALID; } // html uri String htmlUri = event.getHtmlUri(); if (!StringUtils.isEmpty(htmlUri)) { // TODO: convert this desktop url into a mobile one? // htmlUri = htmlUri.replace("/event?", "/mevent?"); // but a little more robust map.put(Events.HTML_URI, htmlUri); } // title String title = event.getTitle(); if (!StringUtils.isEmpty(title)) { map.put(Events.TITLE, title); } // content String content = event.getContent(); if (!StringUtils.isEmpty(content)) { map.put(Events.DESCRIPTION, content); } // where String where = event.getWhere(); if (!StringUtils.isEmpty(where)) { map.put(Events.EVENT_LOCATION, where); } // Calendar ID map.put(Events.CALENDAR_ID, syncInfo.calendarId); // comments uri String commentsUri = event.getCommentsUri(); if (commentsUri != null) { map.put(Events.COMMENTS_URI, commentsUri); } boolean timesSet = false; // see if there are any reminders for this event if (event.getReminders() != null) { // just store that we have reminders. the caller will have // to update the reminders table separately. map.put(Events.HAS_ALARM, 1); } // see if there are any extended properties for this event if (event.getExtendedProperties() != null) { // just store that we have extended properties. the caller will have // to update the extendedproperties table separately. map.put(Events.HAS_EXTENDED_PROPERTIES, 1); } // dtstart & dtend When when = event.getFirstWhen(); if (when != null) { String startTime = when.getStartTime(); if (!StringUtils.isEmpty(startTime)) { time.parse3339(startTime); // we also stash away the event's timezone. // this timezone might get overwritten below, if this event is // a recurrence (recurrences are defined in terms of the // timezone of the creator of the event). // note that we treat all day events as occurring in the UTC timezone, so // an event on 05/08/2007 occurs on 05/08/2007, no matter what timezone the device // is in. // TODO: handle the "floating" timezone. if (time.allDay) { map.put(Events.ALL_DAY, 1); map.put(Events.EVENT_TIMEZONE, Time.TIMEZONE_UTC); } else { map.put(Events.EVENT_TIMEZONE, syncInfo.calendarTimezone); } long dtstart = time.toMillis(false /* use isDst */); if (dtstart < 0) { if (Config.LOGD) { Log.d(TAG, "dtstart out of range: " + startTime); } map.put(Events.DTSTART, -1); // Flag to caller that date is out of range return ENTRY_INVALID; } map.put(Events.DTSTART, dtstart); timesSet = true; } String endTime = when.getEndTime(); if (!StringUtils.isEmpty(endTime)) { time.parse3339(endTime); long dtend = time.toMillis(false /* use isDst */); if (dtend < 0) { if (Config.LOGD) { Log.d(TAG, "dtend out of range: " + endTime); } map.put(Events.DTSTART, -1); // Flag to caller that date is out of range return ENTRY_INVALID; } map.put(Events.DTEND, dtend); } } // rrule String recurrence = event.getRecurrence(); if (!TextUtils.isEmpty(recurrence)) { ICalendar.Component recurrenceComponent = new ICalendar.Component("DUMMY", null /* parent */); ICalendar ical = null; try { ICalendar.parseComponent(recurrenceComponent, recurrence); } catch (ICalendar.FormatException fe) { if (Config.LOGD) { Log.d(TAG, "Unable to parse recurrence: " + recurrence); } return ENTRY_INVALID; } if (!RecurrenceSet.populateContentValues(recurrenceComponent, map)) { return ENTRY_INVALID; } timesSet = true; } if (!timesSet) { return ENTRY_INVALID; } map.put(SyncConstValue._SYNC_ACCOUNT, getAccount()); return ENTRY_OK; }
/** * Parse the given string as a RFC 3339 timestamp, returning the value as milliseconds since the * epoch. */ public static long parseTime(String time) { sTime.parse3339(time); return sTime.toMillis(false); }
protected void showDonationView(int status) { HashMap<String, Time> donations = new HashMap<String, Time>(); if (mCursor.moveToFirst()) { do { String productId = mCursor.getString(mCursor.getColumnIndex(Donations.PRODUCT_ID)); Time time = new Time(); String purchaseTime = mCursor.getString(mCursor.getColumnIndex(Donations.PURCHASE_TIME)); time.parse3339(purchaseTime); donations.put(productId, time); } while (mCursor.moveToNext()); } TextView tv = (TextView) findViewById(R.id.donate_text); if (status == BILLING_CANNOT_CONNECT) { tv.setText( "ERROR:\nCannot connect to Google Play application. Your version of app" + " may be out of date. You can continue to use this app but certain" + " features may not be available."); } else if (status == BILLING_NOT_SUPPORTED) { tv.setText( "ERROR:\nGoogle Play in-app billing is not available this time. You can" + " continue to use this app but certain features may not be available."); } else if (status == BILLING_ERROR_RESTORE) { tv.setText( "ERROR:\nThere was an error trying to restore your past donations. This" + " could be a temporary failure. Please try again later."); } else { tv.setText( "Please consider donating to help me recover my costs to develop" + " the app and provide you with data updates. You may also choose not to" + " donate at all and that is fine too." + "\n\n" + "You will be redirected to Google Play checkout to allow you to securely" + " complete your payment transaction." + "\n\n" + "Please donate generously to show your appreciation."); tv = (TextView) findViewById(R.id.donate_level_label); LinearLayout layout = (LinearLayout) findViewById(R.id.donate_level_layout); layout.removeAllViews(); int count = mDonationLevels.length - donations.size(); for (int i = 0; i < mDonationLevels.length; ++i) { DonationLevel level = mDonationLevels[i]; if (!donations.containsKey(level.productId)) { View row = addRow(layout, level.description, FormatUtils.formatCurrency(level.amount)); row.setTag(level.productId); row.setOnClickListener(this); row.setBackgroundResource(UiUtils.getRowSelector(i, count)); } } if (layout.getChildCount() > 0) { tv.setVisibility(View.VISIBLE); layout.setVisibility(View.VISIBLE); } else { tv.setVisibility(View.GONE); layout.setVisibility(View.GONE); } } tv = (TextView) findViewById(R.id.donate_text2); LinearLayout layout = (LinearLayout) findViewById(R.id.past_donations_layout); layout.removeAllViews(); if (donations.isEmpty()) { Application.sDonationDone = false; addRow(layout, "No donations made yet"); tv.setVisibility(View.GONE); } else { Application.sDonationDone = true; for (String productId : donations.keySet()) { Time time = donations.get(productId); DonationLevel level = getDonationLevel(productId); if (level != null) { addRow( layout, TimeUtils.formatDateTimeLocal(getActivity(), time.toMillis(true)), FormatUtils.formatCurrency(level.amount)); } } tv.setText( "You can restore the above donations on your other devices by" + " simply visiting this screen on those devices."); tv.setVisibility(View.VISIBLE); } setContentShown(true); }