summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/android/calendar/alerts/AlarmManagerInterface.java10
-rw-r--r--src/com/android/calendar/alerts/AlertActivity.java14
-rw-r--r--src/com/android/calendar/alerts/AlertReceiver.java20
-rw-r--r--src/com/android/calendar/alerts/AlertService.java67
-rw-r--r--src/com/android/calendar/alerts/AlertUtils.java27
-rw-r--r--src/com/android/calendar/alerts/SnoozeAlarmsService.java3
-rw-r--r--src/com/android/calendar/event/EditEventView.java134
7 files changed, 212 insertions, 63 deletions
diff --git a/src/com/android/calendar/alerts/AlarmManagerInterface.java b/src/com/android/calendar/alerts/AlarmManagerInterface.java
new file mode 100644
index 00000000..5ee83734
--- /dev/null
+++ b/src/com/android/calendar/alerts/AlarmManagerInterface.java
@@ -0,0 +1,10 @@
+package com.android.calendar.alerts;
+
+import android.app.PendingIntent;
+
+/**
+ * AlarmManager abstracted to an interface for testability.
+ */
+public interface AlarmManagerInterface {
+ public void set(int type, long triggerAtMillis, PendingIntent operation);
+}
diff --git a/src/com/android/calendar/alerts/AlertActivity.java b/src/com/android/calendar/alerts/AlertActivity.java
index d22408fd..12d7b10a 100644
--- a/src/com/android/calendar/alerts/AlertActivity.java
+++ b/src/com/android/calendar/alerts/AlertActivity.java
@@ -124,20 +124,6 @@ public class AlertActivity extends Activity implements OnClickListener {
}
@Override
- protected void onInsertComplete(int token, Object cookie, Uri uri) {
- if (uri != null) {
- Long alarmTime = (Long) cookie;
-
- if (alarmTime != 0) {
- // Set a new alarm to go off after the snooze delay.
- // TODO make provider schedule this automatically when
- // inserting an alarm
- AlertUtils.scheduleAlarm(AlertActivity.this, null, alarmTime);
- }
- }
- }
-
- @Override
protected void onUpdateComplete(int token, Object cookie, int result) {
// Ignore
}
diff --git a/src/com/android/calendar/alerts/AlertReceiver.java b/src/com/android/calendar/alerts/AlertReceiver.java
index b8c38770..1991a4d1 100644
--- a/src/com/android/calendar/alerts/AlertReceiver.java
+++ b/src/com/android/calendar/alerts/AlertReceiver.java
@@ -219,16 +219,16 @@ public class AlertReceiver extends BroadcastReceiver {
public static NotificationWrapper makeBasicNotification(Context context, String title,
String summaryText, long startMillis, long endMillis, long eventId,
- int notificationId, boolean doPopup) {
+ int notificationId, boolean doPopup, int priority) {
Notification n = buildBasicNotification(new Notification.Builder(context),
context, title, summaryText, startMillis, endMillis, eventId, notificationId,
- doPopup, false, false);
+ doPopup, priority, false);
return new NotificationWrapper(n, notificationId, eventId, startMillis, endMillis, doPopup);
}
private static Notification buildBasicNotification(Notification.Builder notificationBuilder,
Context context, String title, String summaryText, long startMillis, long endMillis,
- long eventId, int notificationId, boolean doPopup, boolean highPriority,
+ long eventId, int notificationId, boolean doPopup, int priority,
boolean addActionButtons) {
Resources resources = context.getResources();
if (title == null || title.length() == 0) {
@@ -258,13 +258,9 @@ public class AlertReceiver extends BroadcastReceiver {
notificationBuilder.setWhen(0);
if (Utils.isJellybeanOrLater()) {
- // Setting to a higher priority will encourage notification manager to expand the
- // notification.
- if (highPriority) {
- notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
- } else {
- notificationBuilder.setPriority(Notification.PRIORITY_DEFAULT);
- }
+ // Should be one of the values in Notification (ie. Notification.PRIORITY_HIGH, etc).
+ // A higher priority will encourage notification manager to expand it.
+ notificationBuilder.setPriority(priority);
}
if (addActionButtons) {
@@ -313,11 +309,11 @@ public class AlertReceiver extends BroadcastReceiver {
*/
public static NotificationWrapper makeExpandingNotification(Context context, String title,
String summaryText, String description, long startMillis, long endMillis, long eventId,
- int notificationId, boolean doPopup, boolean highPriority) {
+ int notificationId, boolean doPopup, int priority) {
Notification.Builder basicBuilder = new Notification.Builder(context);
Notification notification = buildBasicNotification(basicBuilder, context, title,
summaryText, startMillis, endMillis, eventId, notificationId, doPopup,
- highPriority, true);
+ priority, true);
if (Utils.isJellybeanOrLater()) {
// Create a new-style expanded notification
Notification.BigTextStyle expandedBuilder = new Notification.BigTextStyle(
diff --git a/src/com/android/calendar/alerts/AlertService.java b/src/com/android/calendar/alerts/AlertService.java
index ac1ca26d..9811dabf 100644
--- a/src/com/android/calendar/alerts/AlertService.java
+++ b/src/com/android/calendar/alerts/AlertService.java
@@ -16,7 +16,6 @@
package com.android.calendar.alerts;
-import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
@@ -233,12 +232,13 @@ public class AlertService extends Service {
return false;
}
- return generateAlerts(context, nm, prefs, alertCursor, currentTime, MAX_NOTIFICATIONS);
+ return generateAlerts(context, nm, AlertUtils.createAlarmManager(context), prefs,
+ alertCursor, currentTime, MAX_NOTIFICATIONS);
}
public static boolean generateAlerts(Context context, NotificationMgr nm,
- SharedPreferences prefs, Cursor alertCursor, final long currentTime,
- final int maxNotifications) {
+ AlarmManagerInterface alarmMgr, SharedPreferences prefs, Cursor alertCursor,
+ final long currentTime, final int maxNotifications) {
if (DEBUG) {
Log.d(TAG, "alertCursor count:" + alertCursor.getCount());
}
@@ -311,7 +311,8 @@ public class AlertService extends Service {
info.allDay, info.location);
notification = AlertReceiver.makeBasicNotification(context, info.eventName,
summaryText, info.startMillis, info.endMillis, info.eventId,
- AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, false);
+ AlertUtils.EXPIRED_GROUP_NOTIFICATION_ID, false,
+ Notification.PRIORITY_MIN);
} else {
// Multiple expired events are listed in a digest.
notification = AlertReceiver.makeDigestNotification(context,
@@ -349,7 +350,7 @@ public class AlertService extends Service {
// Schedule the next silent refresh time so notifications will change
// buckets (eg. drop into expired digest, etc).
if (nextRefreshTime < Long.MAX_VALUE && nextRefreshTime > currentTime) {
- AlertUtils.scheduleNextNotificationRefresh(context, null, nextRefreshTime);
+ AlertUtils.scheduleNextNotificationRefresh(context, alarmMgr, nextRefreshTime);
if (DEBUG) {
long minutesBeforeRefresh = (nextRefreshTime - currentTime) / MINUTE_MS;
Time time = new Time();
@@ -441,18 +442,27 @@ public class AlertService extends Service {
}
private static long getNextRefreshTime(NotificationInfo info, long currentTime) {
- // We change an event's priority bucket at 15 minutes into the event (so recently started
- // concurrent events stay high priority)
+ long startAdjustedForAllDay = info.startMillis;
+ long endAdjustedForAllDay = info.endMillis;
+ if (info.allDay) {
+ Time t = new Time();
+ startAdjustedForAllDay = Utils.convertAlldayUtcToLocal(t, info.startMillis,
+ Time.getCurrentTimezone());
+ endAdjustedForAllDay = Utils.convertAlldayUtcToLocal(t, info.startMillis,
+ Time.getCurrentTimezone());
+ }
+
+ // We change an event's priority bucket at 15 minutes into the event or 1/4 event duration.
long nextRefreshTime = Long.MAX_VALUE;
- long gracePeriodCutoff = info.startMillis +
- getGracePeriodMs(info.startMillis, info.endMillis);
+ long gracePeriodCutoff = startAdjustedForAllDay +
+ getGracePeriodMs(startAdjustedForAllDay, endAdjustedForAllDay, info.allDay);
if (gracePeriodCutoff > currentTime) {
nextRefreshTime = Math.min(nextRefreshTime, gracePeriodCutoff);
}
// ... and at the end (so expiring ones drop into a digest).
- if (info.endMillis > currentTime && info.endMillis > gracePeriodCutoff) {
- nextRefreshTime = Math.min(nextRefreshTime, info.endMillis);
+ if (endAdjustedForAllDay > currentTime && endAdjustedForAllDay > gracePeriodCutoff) {
+ nextRefreshTime = Math.min(nextRefreshTime, endAdjustedForAllDay);
}
return nextRefreshTime;
}
@@ -595,16 +605,12 @@ public class AlertService extends Service {
// Adjust for all day events to ensure the right bucket. Don't use the 1/4 event
// duration grace period for these.
- long gracePeriodMs;
long beginTimeAdjustedForAllDay = beginTime;
String tz = null;
if (allDay) {
tz = TimeZone.getDefault().getID();
beginTimeAdjustedForAllDay = Utils.convertAlldayUtcToLocal(null, beginTime,
tz);
- gracePeriodMs = MIN_DEPRIORITIZE_GRACE_PERIOD_MS;
- } else {
- gracePeriodMs = getGracePeriodMs(beginTime, endTime);
}
// Handle multiple alerts for the same event ID.
@@ -653,7 +659,8 @@ public class AlertService extends Service {
// TODO: Prioritize by "primary" calendar
eventIds.put(eventId, newInfo);
- long highPriorityCutoff = currentTime - gracePeriodMs;
+ long highPriorityCutoff = currentTime -
+ getGracePeriodMs(beginTime, endTime, allDay);
if (beginTimeAdjustedForAllDay > highPriorityCutoff) {
// High priority = future events or events that just started
@@ -676,8 +683,14 @@ public class AlertService extends Service {
/**
* High priority cutoff should be 1/4 event duration or 15 min, whichever is longer.
*/
- private static long getGracePeriodMs(long beginTime, long endTime) {
- return Math.max(MIN_DEPRIORITIZE_GRACE_PERIOD_MS, ((endTime - beginTime) / 4));
+ private static long getGracePeriodMs(long beginTime, long endTime, boolean allDay) {
+ if (allDay) {
+ // We don't want all day events to be high priority for hours, so automatically
+ // demote these after 15 min.
+ return MIN_DEPRIORITIZE_GRACE_PERIOD_MS;
+ } else {
+ return Math.max(MIN_DEPRIORITIZE_GRACE_PERIOD_MS, ((endTime - beginTime) / 4));
+ }
}
private static String getDigestTitle(ArrayList<NotificationInfo> events) {
@@ -696,11 +709,15 @@ public class AlertService extends Service {
private static void postNotification(NotificationInfo info, String summaryText,
Context context, boolean highPriority, NotificationPrefs prefs,
NotificationMgr notificationMgr, int notificationId) {
+ int priorityVal = Notification.PRIORITY_DEFAULT;
+ if (highPriority) {
+ priorityVal = Notification.PRIORITY_HIGH;
+ }
+
String tickerText = getTickerText(info.eventName, info.location);
NotificationWrapper notification = AlertReceiver.makeExpandingNotification(context,
info.eventName, summaryText, info.description, info.startMillis,
- info.endMillis, info.eventId, notificationId, prefs.getDoPopup(),
- highPriority);
+ info.endMillis, info.eventId, notificationId, prefs.getDoPopup(), priorityVal);
boolean quietUpdate = true;
String ringtone = NotificationPrefs.EMPTY_RINGTONE;
@@ -868,10 +885,8 @@ public class AlertService extends Service {
private void doTimeChanged() {
ContentResolver cr = getContentResolver();
- Object service = getSystemService(Context.ALARM_SERVICE);
- AlarmManager manager = (AlarmManager) service;
// TODO Move this into Provider
- rescheduleMissedAlarms(cr, this, manager);
+ rescheduleMissedAlarms(cr, this, AlertUtils.createAlarmManager(this));
updateAlertNotification(this);
}
@@ -900,8 +915,8 @@ public class AlertService extends Service {
* @param context the Context
* @param manager the AlarmManager
*/
- public static final void rescheduleMissedAlarms(ContentResolver cr, Context context,
- AlarmManager manager) {
+ private static final void rescheduleMissedAlarms(ContentResolver cr, Context context,
+ AlarmManagerInterface manager) {
// Get all the alerts that have been scheduled but have not fired
// and should have fired by now and are not too old.
long now = System.currentTimeMillis();
diff --git a/src/com/android/calendar/alerts/AlertUtils.java b/src/com/android/calendar/alerts/AlertUtils.java
index 9f160c6b..f68f5224 100644
--- a/src/com/android/calendar/alerts/AlertUtils.java
+++ b/src/com/android/calendar/alerts/AlertUtils.java
@@ -80,6 +80,20 @@ public class AlertUtils {
private static final int FLUSH_INTERVAL_MS = FLUSH_INTERVAL_DAYS * 24 * 60 * 60 * 1000;
/**
+ * Creates an AlarmManagerInterface that wraps a real AlarmManager. The alarm code
+ * was abstracted to an interface to make it testable.
+ */
+ public static AlarmManagerInterface createAlarmManager(Context context) {
+ final AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ return new AlarmManagerInterface() {
+ @Override
+ public void set(int type, long triggerAtMillis, PendingIntent operation) {
+ mgr.set(type, triggerAtMillis, operation);
+ }
+ };
+ }
+
+ /**
* Schedules an alarm intent with the system AlarmManager that will notify
* listeners when a reminder should be fired. The provider will keep
* scheduled reminders up to date but apps may use this to implement snooze
@@ -90,7 +104,8 @@ public class AlertUtils {
* @param manager The AlarmManager to use or null
* @param alarmTime The time to fire the intent in UTC millis since epoch
*/
- public static void scheduleAlarm(Context context, AlarmManager manager, long alarmTime) {
+ public static void scheduleAlarm(Context context, AlarmManagerInterface manager,
+ long alarmTime) {
scheduleAlarmHelper(context, manager, alarmTime, false);
}
@@ -98,17 +113,13 @@ public class AlertUtils {
* Schedules the next alarm to silently refresh the notifications. Note that if there
* is a pending silent refresh alarm, it will be replaced with this one.
*/
- static void scheduleNextNotificationRefresh(Context context, AlarmManager manager,
+ static void scheduleNextNotificationRefresh(Context context, AlarmManagerInterface manager,
long alarmTime) {
scheduleAlarmHelper(context, manager, alarmTime, true);
}
- private static void scheduleAlarmHelper(Context context, AlarmManager manager, long alarmTime,
- boolean quietUpdate) {
- if (manager == null) {
- manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- }
-
+ private static void scheduleAlarmHelper(Context context, AlarmManagerInterface manager,
+ long alarmTime, boolean quietUpdate) {
int alarmType = AlarmManager.RTC_WAKEUP;
Intent intent = new Intent(CalendarContract.ACTION_EVENT_REMINDER);
intent.setClass(context, AlertReceiver.class);
diff --git a/src/com/android/calendar/alerts/SnoozeAlarmsService.java b/src/com/android/calendar/alerts/SnoozeAlarmsService.java
index 2eac1a71..6ef983d5 100644
--- a/src/com/android/calendar/alerts/SnoozeAlarmsService.java
+++ b/src/com/android/calendar/alerts/SnoozeAlarmsService.java
@@ -80,7 +80,8 @@ public class SnoozeAlarmsService extends IntentService {
ContentValues values = AlertUtils.makeContentValues(eventId, eventStart, eventEnd,
alarmTime, 0);
resolver.insert(uri, values);
- AlertUtils.scheduleAlarm(SnoozeAlarmsService.this, null, alarmTime);
+ AlertUtils.scheduleAlarm(SnoozeAlarmsService.this, AlertUtils.createAlarmManager(this),
+ alarmTime);
}
AlertService.updateAlertNotification(this);
stopSelf();
diff --git a/src/com/android/calendar/event/EditEventView.java b/src/com/android/calendar/event/EditEventView.java
index 57d56b14..1fbc8d5e 100644
--- a/src/com/android/calendar/event/EditEventView.java
+++ b/src/com/android/calendar/event/EditEventView.java
@@ -24,12 +24,14 @@ import android.app.ProgressDialog;
import android.app.Service;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
+import android.database.MatrixCursor;
import android.graphics.drawable.Drawable;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
@@ -43,14 +45,17 @@ import android.text.format.DateUtils;
import android.text.format.Time;
import android.text.util.Rfc822Tokenizer;
import android.util.Log;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CalendarView;
import android.widget.CheckBox;
@@ -64,6 +69,7 @@ import android.widget.ResourceCursorAdapter;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
import android.widget.TimePicker;
import com.android.calendar.CalendarEventModel;
@@ -93,6 +99,7 @@ import java.util.Formatter;
import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;
+import java.util.TreeMap;
public class EditEventView implements View.OnClickListener, DialogInterface.OnCancelListener,
DialogInterface.OnClickListener, OnItemSelectedListener {
@@ -100,6 +107,16 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
private static final String GOOGLE_SECONDARY_CALENDAR = "calendar.google.com";
private static final String PERIOD_SPACE = ". ";
+ // Constants used for title autocompletion.
+ private static final String[] EVENT_PROJECTION = new String[] {
+ Events._ID,
+ Events.TITLE,
+ };
+ private static final int EVENT_INDEX_ID = 0;
+ private static final int EVENT_INDEX_TITLE = 1;
+ private static final String TITLE_WHERE = Events.TITLE + " LIKE ?";
+ private static final int MAX_TITLE_SUGGESTIONS = 4;
+
ArrayList<View> mEditOnlyList = new ArrayList<View>();
ArrayList<View> mEditViewList = new ArrayList<View>();
ArrayList<View> mViewOnlyList = new ArrayList<View>();
@@ -121,7 +138,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
Spinner mAvailabilitySpinner;
Spinner mAccessLevelSpinner;
RadioGroup mResponseRadioGroup;
- TextView mTitleTextView;
+ AutoCompleteTextView mTitleTextView;
TextView mLocationTextView;
TextView mDescriptionTextView;
TextView mWhenView;
@@ -627,6 +644,106 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
}
/**
+ * Adapter for title auto completion.
+ */
+ private static class TitleAdapter extends ResourceCursorAdapter {
+ private final ContentResolver mContentResolver;
+
+ public TitleAdapter(Context context) {
+ super(context, android.R.layout.simple_dropdown_item_1line, null, 0);
+ mContentResolver = context.getContentResolver();
+ }
+
+ @Override
+ public int getCount() {
+ return Math.min(MAX_TITLE_SUGGESTIONS, super.getCount());
+ }
+
+ private static String getTitleAtCursor(Cursor cursor) {
+ return cursor.getString(EVENT_INDEX_TITLE);
+ }
+
+ @Override
+ public final String convertToString(Cursor cursor) {
+ return getTitleAtCursor(cursor);
+ }
+
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ TextView textView = (TextView) view;
+ textView.setText(getTitleAtCursor(cursor));
+ }
+
+ @Override
+ public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
+ String filter = constraint == null ? "" : constraint.toString() + "%";
+ if (filter.isEmpty()) {
+ return null;
+ }
+ long startTime = System.currentTimeMillis();
+
+ // Query all titles prefixed with the constraint. There is no way to insert
+ // 'DISTINCT' or 'GROUP BY' to get rid of dupes, so use post-processing to
+ // remove dupes. We will order query results by descending event ID to show
+ // results that were most recently inputted.
+ Cursor tempCursor = mContentResolver.query(Events.CONTENT_URI, EVENT_PROJECTION,
+ TITLE_WHERE, new String[] { filter }, Events._ID + " DESC");
+ if (tempCursor != null) {
+ try {
+ // Post process query results.
+ Cursor c = uniqueTitlesCursor(tempCursor);
+
+ // Log the processing duration.
+ long duration = System.currentTimeMillis() - startTime;
+ StringBuilder msg = new StringBuilder();
+ msg.append("Autocomplete of ");
+ msg.append(constraint);
+ msg.append(": title query match took ");
+ msg.append(duration);
+ msg.append("ms.");
+ Log.d(TAG, msg.toString());
+ return c;
+ } finally {
+ tempCursor.close();
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Post-process the query results to return the first MAX_TITLE_SUGGESTIONS
+ * unique titles in alphabetical order.
+ */
+ private Cursor uniqueTitlesCursor(Cursor cursor) {
+ TreeMap<String, String[]> titleToQueryResults =
+ new TreeMap<String, String[]>(String.CASE_INSENSITIVE_ORDER);
+ int numColumns = cursor.getColumnCount();
+ cursor.moveToPosition(-1);
+
+ // Remove dupes.
+ while ((titleToQueryResults.size() < MAX_TITLE_SUGGESTIONS) && cursor.moveToNext()) {
+ String title = getTitleAtCursor(cursor).trim();
+ String data[] = new String[numColumns];
+ if (!titleToQueryResults.containsKey(title)) {
+ for (int i = 0; i < numColumns; i++) {
+ data[i] = cursor.getString(i);
+ }
+ titleToQueryResults.put(title, data);
+ }
+ }
+
+ // Copy the sorted results to a new cursor.
+ MatrixCursor newCursor = new MatrixCursor(EVENT_PROJECTION);
+ for (String[] result : titleToQueryResults.values()) {
+ newCursor.addRow(result);
+ }
+ newCursor.moveToFirst();
+ return newCursor;
+ }
+ }
+
+ /**
* Does prep steps for saving a calendar event.
*
* This triggers a parse of the attendees list and checks if the event is
@@ -829,7 +946,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
// cache all the widgets
mCalendarsSpinner = (Spinner) view.findViewById(R.id.calendars_spinner);
- mTitleTextView = (TextView) view.findViewById(R.id.title);
+ mTitleTextView = (AutoCompleteTextView) view.findViewById(R.id.title);
mLocationTextView = (TextView) view.findViewById(R.id.location);
mDescriptionTextView = (TextView) view.findViewById(R.id.description);
mTimezoneLabel = (TextView) view.findViewById(R.id.timezone_label);
@@ -863,6 +980,19 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
mAttendeesList = (MultiAutoCompleteTextView) view.findViewById(R.id.attendees);
mTitleTextView.setTag(mTitleTextView.getBackground());
+ mTitleTextView.setAdapter(new TitleAdapter(activity));
+ mTitleTextView.setOnEditorActionListener(new OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ // Dismiss the suggestions dropdown. Return false so the other
+ // side effects still occur (soft keyboard going away, etc.).
+ mTitleTextView.dismissDropDown();
+ }
+ return false;
+ }
+ });
+
mLocationTextView.setTag(mLocationTextView.getBackground());
mDescriptionTextView.setTag(mDescriptionTextView.getBackground());
mRepeatsSpinner.setTag(mRepeatsSpinner.getBackground());