Java tutorial
/* * ================================================================================================= * Copyright (C) 2014 Martin Albedinsky [Wolf-ITechnologies] * ================================================================================================= * Licensed under the Apache License, Version 2.0 or later (further "License" only). * ------------------------------------------------------------------------------------------------- * You may use this file only in compliance with the License. More details and copy of this License * you may obtain at * * http://www.apache.org/licenses/LICENSE-2.0 * * You can redistribute, modify or publish any part of the code written within this file but as it * is described in the License, the software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES or CONDITIONS OF ANY KIND. * * See the License for the specific language governing permissions and limitations under the License. * ================================================================================================= */ package com.wit.android.support.content.intent; import android.app.Activity; import android.content.ContentUris; import android.content.Intent; import android.net.Uri; import android.provider.CalendarContract; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import android.support.v4.app.Fragment; import android.text.TextUtils; import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * <h3>Class Overview</h3> * Intent builder specialized to create CALENDAR intents. * * @author Martin Albedinsky */ public class CalendarIntent extends BaseIntent<CalendarIntent> { /** * Interface =================================================================================== */ /** * <h3>Annotation Overview</h3> * Defines an annotation for determining set of allowed flags for {@link #type(int)} method. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ TYPE_VIEW, TYPE_INSERT_EVENT, TYPE_EDIT_EVENT, TYPE_VIEW_EVENT }) public @interface Type { } /** * <h3>Annotation Overview</h3> * Defines an annotation for determining set of allowed flags for {@link #availability(int)} method. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ AVAILABILITY_BUSY, AVAILABILITY_FREE, AVAILABILITY_TENTATIVE }) public @interface Availability { } /** * Constants =================================================================================== */ /** * Log TAG. */ private static final String TAG = "CalendarIntent"; /** * Flag indicating whether the output trough log-cat is enabled or not. */ // private static final boolean LOG_ENABLED = true; /** * Flag indicating whether the debug output trough log-cat is enabled or not. */ // private static final boolean DEBUG_ENABLED = true; /** * Flag to identify CalendarIntent as intent to open calendar. Can be passed only to {@link #type(int)}. */ public static final int TYPE_VIEW = 0x01; /** * Flag to identify CalendarIntent as intent to create new calendar event. Can be passed only to * {@link #type(int)}. */ public static final int TYPE_INSERT_EVENT = 0x02; /** * Flag to identify CalendarIntent as intent to edit existing calendar event. Can be passed only * to {@link #type(int)}. */ public static final int TYPE_EDIT_EVENT = 0x03; /** * Flag to identify CalendarIntent as intent to view existing calendar event. Can be passed only * to {@link #type(int)}. */ public static final int TYPE_VIEW_EVENT = 0x04; /** * Flag to identify BUSY availability for the newly creating calendar event. * See {@link CalendarContract.Events#AVAILABILITY_BUSY} for additional info. */ public static final int AVAILABILITY_BUSY = CalendarContract.Events.AVAILABILITY_BUSY; /** * Flag to identify FREE availability for the newly creating calendar event. * See {@link CalendarContract.Events#AVAILABILITY_FREE} for additional info. */ public static final int AVAILABILITY_FREE = CalendarContract.Events.AVAILABILITY_FREE; /** * Flag to identify TENTATIVE availability for the newly creating calendar event. * See {@link CalendarContract.Events#AVAILABILITY_TENTATIVE} for additional info. */ public static final int AVAILABILITY_TENTATIVE = 0x02; /** * Static members ============================================================================== */ /** * Members ===================================================================================== */ /** * The type of intent creating by this builder. */ private int mType = TYPE_INSERT_EVENT; /** * The id of newly creating or already existing calendar event. */ private long mEventId; /** * The time for newly creating calendar event. */ private long mBeginTime, mEndTime; /** * The title for newly creating calendar event. */ private String mTitle; /** * The description for newly creating calendar event. */ private String mDescription; /** * The locationQuery for newly creating calendar event. */ private String mLocation; /** * The availability for newly creating calendar event. */ private int mAvailability = AVAILABILITY_BUSY; /** * Constructors ================================================================================ */ /** * Creates a new instance of CalendarIntent for the given <var>activity</var> context with * the <b>begin</b> time set to the current one and <b>end</b> time set to +1 after the <b>begin</b> * time. See {@link com.wit.android.support.content.intent.BaseIntent#BaseIntent(android.app.Activity)} * for additional info. */ public CalendarIntent(@NonNull Activity activity) { super(activity); this.init(); } /** * Creates a new instance of CalendarIntent for the given <var>fragment</var> context with * the <b>begin</b> time set to the current one and <b>end</b> time set to +1 after the <b>begin</b> * time. See {@link com.wit.android.support.content.intent.BaseIntent#BaseIntent(android.support.v4.app.Fragment)} * for additional info. */ public CalendarIntent(@NonNull Fragment fragment) { super(fragment); this.init(); } /** * Methods ===================================================================================== */ /** * Public -------------------------------------------------------------------------------------- */ /** * Wrapped {@link System#currentTimeMillis()}. */ public static long currentTime() { return System.currentTimeMillis(); } /** */ @Nullable @Override public Intent buildIntent() { switch (mType) { case TYPE_VIEW: if (checkTime(mBeginTime, "Time isn't valid.")) { final Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon(); builder.appendPath("time"); ContentUris.appendId(builder, mBeginTime); /** * Build the intent. */ return new Intent(Intent.ACTION_VIEW).setData(builder.build()); } break; case TYPE_INSERT_EVENT: if (!checkTime(mBeginTime, "Begin time(" + mBeginTime + ") isn't valid.")) { return null; } if (!checkTime(mEndTime, "End time(" + mEndTime + ") isn't valid.")) { return null; } if (mEndTime <= mBeginTime) { this.logMessage( "End time(" + mEndTime + ") is wrong specified before/at begin time(" + mBeginTime + ")."); return null; } /** * Build the intent. */ final Intent intent = new Intent(Intent.ACTION_INSERT).setData(CalendarContract.Events.CONTENT_URI) .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, mBeginTime) .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, mEndTime) .putExtra(CalendarContract.Events.TITLE, mTitle) .putExtra(CalendarContract.Events.DESCRIPTION, mDescription) .putExtra(CalendarContract.Events.EVENT_LOCATION, mLocation) .putExtra(CalendarContract.Events.AVAILABILITY, mAvailability); // todo: add extra emails. // intent.putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com"); return intent; case TYPE_EDIT_EVENT: if (checkEventId()) { /** * Build the intent. */ final Intent eventIntent = new Intent(Intent.ACTION_EDIT); eventIntent.setData(ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, mEventId)); if (!TextUtils.isEmpty(mTitle)) { eventIntent.putExtra(CalendarContract.Events.TITLE, mTitle); } return eventIntent; } break; case TYPE_VIEW_EVENT: if (checkEventId()) { /** * Build the intent. */ return new Intent(Intent.ACTION_VIEW) .setData(ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, mEventId)); } break; } return null; } /** * Getters + Setters --------------------------------------------------------------------------- */ /** * Returns current type of the calendar intent which will be created by this intent builder. * * @return One of: {@link #TYPE_VIEW}, {@link #TYPE_INSERT_EVENT}, {@link #TYPE_EDIT_EVENT}, * {@link #TYPE_VIEW_EVENT}. */ @Type public int getType() { return mType; } /** * Sets the type of calendar intent which should be created by this intent builder. * * @param type One of: {@link #TYPE_VIEW}, {@link #TYPE_INSERT_EVENT}, {@link #TYPE_EDIT_EVENT}, * {@link #TYPE_VIEW_EVENT}. * @return This intent builder to allow methods chaining. */ public CalendarIntent type(@Type int type) { switch (type) { case TYPE_VIEW: case TYPE_INSERT_EVENT: case TYPE_EDIT_EVENT: case TYPE_VIEW_EVENT: this.mType = type; } return this; } /** * Returns an id of the calendar event to edit or view within calendar. This id is used only when * the current type is set to: {@link #TYPE_EDIT_EVENT} or {@link #TYPE_VIEW_EVENT}. * * @return Event id. */ public long getEventId() { return mEventId; } /** * Sets an id of the calendar event to edit or view, used only when the current type is set to: * {@link #TYPE_EDIT_EVENT} or {@link #TYPE_VIEW_EVENT}. * * @param eventId Id of the desired calendar event (to edit or view). * @return This intent builder to allow methods chaining. */ public CalendarIntent eventId(long eventId) { this.mEventId = eventId; return this; } /** * Returns begin time for newly creating calendar event. * <p> * <b>Note</b>, that the default begin time is set to the current one ({@link #currentTime()}). * * @return Begin time for calendar event. */ public long getBeginTime() { return mBeginTime; } /** * Sets the begin time for newly creating calendar event used only in case of type: {@link #TYPE_INSERT_EVENT}. * <p> * <b>Note</b>, that the default begin time is set to the current one ({@link #currentTime()}). * * @param beginTime The desired begin time for event in milliseconds. * @return This intent builder to allow methods chaining. * @see #endTime(long) */ public CalendarIntent beginTime(long beginTime) { this.mBeginTime = beginTime; return this; } /** * Returns end time for newly creating calendar event. * <p> * <b>Note</b>, that the default end time is set to +1 of the current begin time ({@link #getBeginTime()}). * * @return End time for calendar event. */ public long getEndTime() { return mEndTime; } /** * Sets the end time for newly creating calendar event used only in case of type: {@link #TYPE_INSERT_EVENT}. * <p> * <b>Note</b>, that the default end time is set to +1 of the current begin time ({@link #getBeginTime()}). * * @param endTime The desired end time for event in milliseconds. * @return This intent builder to allow methods chaining. */ public CalendarIntent endTime(long endTime) { this.mEndTime = endTime; return this; } /** * Returns title for newly creating calendar event. * * @return Title for calendar event. * @see #title(int) * @see #title(String) */ @Nullable public String getTitle() { return mTitle; } /** * Same as {@link #title(String)}, where string will be obtained from the current context wrapper * (activity/fragment). * * @param resId Resource id of the desired title text placed within an application resources. */ public CalendarIntent title(@StringRes int resId) { return title(obtainString(resId)); } /** * Sets the title for newly creating calendar event used only in case of type: {@link #TYPE_INSERT_EVENT}. * * @param title The desired title text. * @return This intent builder to allow methods chaining. * @see #title(int) */ public CalendarIntent title(@Nullable String title) { mTitle = title; return this; } /** * Returns description for newly creating calendar event. * * @return Description for calendar event. * @see #description(int) * @see #description(String) */ @Nullable public String getDescription() { return mDescription; } /** * Same as {@link #description(String)}, where string will be obtained from the current context * wrapper (activity/fragment). * * @param resId Resource id of the desired description text placed within an application resources. */ public CalendarIntent description(@StringRes int resId) { return description(obtainString(resId)); } /** * Sets the description for newly creating calendar event used only in case of type: {@link #TYPE_INSERT_EVENT}. * * @param description The desired description text. * @return This intent builder to allow methods chaining. * @see #description(int) */ public CalendarIntent description(@Nullable String description) { mDescription = description; return this; } /** * Returns locationQuery for newly creating calendar event used only in case of type: {@link #TYPE_INSERT_EVENT}. * * @return Location for calendar event. */ @Nullable public String getLocation() { return mLocation; } /** * Same as {@link #location(String)}, where string will be obtained from the current context wrapper * (activity/fragment). * * @param resId Resource id of the desired locationQuery text placed within an application resources. */ public CalendarIntent location(@StringRes int resId) { return location(obtainString(resId)); } /** * Sets the locationQuery for newly creating calendar event used only in case of type: {@link #TYPE_INSERT_EVENT}. * * @param location The desired locationQuery text. * @return This intent builder to allow methods chaining. * @see #location(int) */ public CalendarIntent location(@Nullable String location) { mLocation = location; return this; } /** * Returns availability flag for newly creating calendar event. * * @return The current availability for event, one of {@link #AVAILABILITY_BUSY}, {@link #AVAILABILITY_FREE}, * {@link #AVAILABILITY_TENTATIVE} or default {@link #AVAILABILITY_BUSY} if wasn't changed yet. */ @Availability public int getAvailability() { return mAvailability; } /** * Sets the availability flag for newly creating calendar event used only in case of type: * {@link #TYPE_INSERT_EVENT}. * <p> * By default, availability is set to {@link #AVAILABILITY_BUSY}. * * @param availability One of {@link #AVAILABILITY_BUSY}, {@link #AVAILABILITY_FREE} or {@link #AVAILABILITY_TENTATIVE}. * @return This intent builder to allow methods chaining. */ public CalendarIntent availability(@Availability int availability) { switch (availability) { case AVAILABILITY_BUSY: case AVAILABILITY_FREE: case AVAILABILITY_TENTATIVE: this.mAvailability = availability; } return this; } /** * Protected ----------------------------------------------------------------------------------- */ /** * Private ------------------------------------------------------------------------------------- */ /** * Initializes default values for this instance of calendar intent builder. */ private void init() { this.mBeginTime = currentTime(); this.mEndTime = mBeginTime + 1; } /** * Checks the current calendar event id. This will also log message in case if the current * event id is invalid, so use this only when the event id is required. * * @return {@code True} if the current id is valid, {@code false} otherwise. */ private boolean checkEventId() { if (mEventId < 0) { this.logMessage("No event id specified."); return false; } return true; } /** * Checks the given value of time. * * @param time Time in milliseconds to check. * @param errorLog Error message to log when the given time is invalid. * @return {@code True} if the passed time is valid ({@code 0}), {@code false} * otherwise. */ private boolean checkTime(long time, String errorLog) { if (time <= 0) { this.logMessage(errorLog); return false; } return true; } /** * Logs the given message as error message into log cat. * * @param message Message to log. */ private void logMessage(String message) { Log.e(TAG, "Can not crate CALENDAR intent. " + message); } /** * Inner classes =============================================================================== */ }