package cgeo.geocaching.calendar; import cgeo.geocaching.R; import cgeo.geocaching.location.GeopointFormatter; import cgeo.geocaching.models.Geocache; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.TextUtils; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.provider.CalendarContract; import android.support.annotation.NonNull; import android.text.Html; import android.text.Spanned; import android.text.style.ImageSpan; import android.view.Gravity; import android.widget.Toast; import java.util.Calendar; import java.util.Date; import org.apache.commons.lang3.StringUtils; class CalendarEntry { @NonNull private final String shortDesc; @NonNull private final Date hiddenDate; @NonNull private final String url; @NonNull private final String personalNote; @NonNull private final String name; @NonNull private final String coords; private final int startTimeMinutes; CalendarEntry(@NonNull final Geocache cache, @NonNull final Date hiddenDate) { this(TextUtils.stripHtml(StringUtils.defaultString(cache.getShortDescription())), hiddenDate, StringUtils.defaultString(cache.getUrl()), StringUtils.defaultString(cache.getPersonalNote()), cache.getName(), cache.getCoords() == null ? "" : cache.getCoords().format(GeopointFormatter.Format.LAT_LON_DECMINUTE_RAW), cache.guessEventTimeMinutes()); } private CalendarEntry(@NonNull final String shortDesc, @NonNull final Date hiddenDate, @NonNull final String url, @NonNull final String personalNote, @NonNull final String name, @NonNull final String coords, final int startTimeMinutes) { this.shortDesc = shortDesc; this.hiddenDate = hiddenDate; this.url = url; this.personalNote = personalNote; this.name = name; this.coords = coords; this.startTimeMinutes = startTimeMinutes; } /** * @return {@code Date} based on hidden date. Time is set to 00:00:00. */ @NonNull private Date parseDate() { try { final Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(hiddenDate.getTime()); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); return cal.getTime(); } catch (final NumberFormatException e) { // cannot happen normally, but static code analysis does not know throw new IllegalStateException("hidden date must be a valid date for cache calendar entries"); } } /** * @return description string with images removed and personal note included */ @NonNull private String parseDescription() { final StringBuilder description = new StringBuilder(); description.append(url); if (StringUtils.isNotBlank(shortDesc)) { // remove images in short description final Spanned spanned = Html.fromHtml(shortDesc, null, null); String text = spanned.toString(); final ImageSpan[] spans = spanned.getSpans(0, spanned.length(), ImageSpan.class); for (int i = spans.length - 1; i >= 0; i--) { text = text.substring(0, spanned.getSpanStart(spans[i])) + text.substring(spanned.getSpanEnd(spans[i])); } if (StringUtils.isNotBlank(text)) { description.append("\n\n"); description.append(text); } } if (StringUtils.isNotBlank(personalNote)) { description.append("\n\n").append(TextUtils.stripHtml(personalNote)); } return description.toString(); } private void addEntryToCalendarInternal(final Context context) { final Date eventDate = parseDate(); final String description = parseDescription(); final Intent intent = new Intent(Intent.ACTION_INSERT) .setData(Uri.parse("content://com.android.calendar/events")) .putExtra(CalendarContract.Events.TITLE, TextUtils.stripHtml(name)) .putExtra(CalendarContract.Events.DESCRIPTION, description) .putExtra(CalendarContract.Events.HAS_ALARM, false) .putExtra(CalendarContract.Events.EVENT_TIMEZONE, "UTC"); final long eventTime = eventDate.getTime(); final int entryStartTimeMinutes = startTimeMinutes; if (entryStartTimeMinutes >= 0) { intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, eventTime + entryStartTimeMinutes * 60000L); } else { intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, eventTime); intent.putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, true); } if (StringUtils.isNotEmpty(coords)) { intent.putExtra(CalendarContract.Events.EVENT_LOCATION, coords); } context.startActivity(intent); } void addEntryToCalendar(final Context context) { try { addEntryToCalendarInternal(context); } catch (final Exception e) { showToast(context, R.string.event_fail); Log.e("addEntryToCalendar", e); } } public void showToast(final Context context, final int res) { final String text = context.getResources().getString(res); final Toast toast = Toast.makeText(context, text, Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 100); toast.show(); } }