summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2015-04-04 20:42:30 +0200
committerJorge Ruesga <jorge@ruesga.com>2015-04-06 21:15:16 +0200
commit877904c3b487029421f9ba6c3606bd2e465fefaa (patch)
treef107de0da5f2e3f95861a53a31aad8ddbdbb9925
parent65e3d0520abbf8dc7da1104e0581ae324407dbf2 (diff)
downloadandroid_packages_apps_Email-877904c3b487029421f9ba6c3606bd2e465fefaa.tar.gz
android_packages_apps_Email-877904c3b487029421f9ba6c3606bd2e465fefaa.tar.bz2
android_packages_apps_Email-877904c3b487029421f9ba6c3606bd2e465fefaa.zip
email: support per-folder notifications
This change enables support to configure per-folder notifications options. Change-Id: I6107340da3438ea223506bb22ff898cca179c1f6 Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
-rw-r--r--res/layout/preference_mailbox_item.xml58
-rw-r--r--res/values/cm_dimens.xml20
-rw-r--r--res/values/cm_strings.xml8
-rw-r--r--res/xml/mailbox_notifications_preferences.xml36
-rw-r--r--src/com/android/email/activity/setup/AccountSettingsFragment.java112
-rw-r--r--src/com/android/email/activity/setup/MailboxSettings.java519
6 files changed, 698 insertions, 55 deletions
diff --git a/res/layout/preference_mailbox_item.xml b/res/layout/preference_mailbox_item.xml
new file mode 100644
index 000000000..07d3ba83f
--- /dev/null
+++ b/res/layout/preference_mailbox_item.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The CyanogenMod Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="48dp"
+ android:background="?android:attr/activatedBackgroundIndicator"
+ android:gravity="center_vertical"
+ android:paddingStart="24dip"
+ android:paddingEnd="?android:attr/scrollbarSize">
+
+ <View
+ android:id="@+id/spacer"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content" />
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="0dip"
+ android:layout_marginEnd="8dip"
+ android:layout_gravity="center" />
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="0dip"
+ android:layout_marginEnd="6dip"
+ android:layout_marginTop="6dip"
+ android:layout_marginBottom="6dip"
+ android:layout_weight="1">
+
+ <TextView android:id="@+android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal" />
+
+ </RelativeLayout>
+
+</LinearLayout>
diff --git a/res/values/cm_dimens.xml b/res/values/cm_dimens.xml
new file mode 100644
index 000000000..6748f80d3
--- /dev/null
+++ b/res/values/cm_dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The CaynogenMod Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Folder settings -->
+ <dimen name="child_folder_indent">8dp</dimen>
+</resources>
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
index 0e3594f64..c0534bfb1 100644
--- a/res/values/cm_strings.xml
+++ b/res/values/cm_strings.xml
@@ -21,4 +21,12 @@
account <xliff:g id="account">%s</xliff:g>. This operation cannot be undone.\n\nContinue?</string>
<string name="deleting_account_msg">Deleting account\u2026</string>
<string name="delete_account_failed">Couldn\'t delete the account</string>
+
+ <!-- Mailbox notification settings activity title [CHAR LIMIT=none] -->
+ <string name="mailbox_notify_settings_activity_title">Notification options</string>
+ <!-- Mailbox settings activity title, with the target folder name [CHAR LIMIT=none] -->
+ <string name="mailbox_notify_settings_activity_title_with_mailbox">Notification options (<xliff:g id="mailbox_name" example="Family">%s</xliff:g>)</string>
+
+ <!-- Name for preference entry which leads to the per-folder notification settings activity -->
+ <string name="folder_notify_settings_pref_title">Folder notification settings</string>
</resources>
diff --git a/res/xml/mailbox_notifications_preferences.xml b/res/xml/mailbox_notifications_preferences.xml
new file mode 100644
index 000000000..76841420c
--- /dev/null
+++ b/res/xml/mailbox_notifications_preferences.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The CyanogenMod Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <CheckBoxPreference
+ android:key="notifications-enabled"
+ android:title="@string/account_settings_notify_label"
+ android:defaultValue="true"
+ android:summary="@string/account_settings_notify_summary" />
+
+ <Preference
+ android:key="notification-ringtone"
+ android:dependency="notifications-enabled"
+ android:title="@string/account_settings_ringtone" />
+
+ <CheckBoxPreference
+ android:key="notification-vibrate"
+ android:dependency="notifications-enabled"
+ android:defaultValue="false"
+ android:title="@string/label_notification_vibrate_title" />
+
+</PreferenceScreen>
diff --git a/src/com/android/email/activity/setup/AccountSettingsFragment.java b/src/com/android/email/activity/setup/AccountSettingsFragment.java
index 49bd8535d..e7abc1cab 100644
--- a/src/com/android/email/activity/setup/AccountSettingsFragment.java
+++ b/src/com/android/email/activity/setup/AccountSettingsFragment.java
@@ -103,12 +103,14 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
private static final String PREFERENCE_QUICK_RESPONSES = "account_quick_responses";
private static final String PREFERENCE_FREQUENCY = "account_check_frequency";
private static final String PREFERENCE_SYNC_WINDOW = "account_sync_window";
- private static final String PREFERENCE_SYNC_SETTINGS = "account_sync_settings";
+ private static final String PREFERENCE_SYNC_SETTINGS = MailboxSettings.PREFERENCE_SYNC_SETTINGS;
private static final String PREFERENCE_SYNC_EMAIL = "account_sync_email";
private static final String PREFERENCE_SYNC_CONTACTS = "account_sync_contacts";
private static final String PREFERENCE_SYNC_CALENDAR = "account_sync_calendar";
private static final String PREFERENCE_BACKGROUND_ATTACHMENTS =
"account_background_attachments";
+ private static final String PREFERENCE_PER_FOLDER_NOTIFICATIONS =
+ MailboxSettings.PREFERENCE_PER_FOLDER_NOTIFICATIONS;
private static final String PREFERENCE_CATEGORY_DATA_USAGE = "data_usage";
private static final String PREFERENCE_CATEGORY_NOTIFICATIONS = "account_notifications";
private static final String PREFERENCE_CATEGORY_SERVER = "account_servers";
@@ -142,6 +144,7 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
private Preference mSyncSettings;
private CheckBoxPreference mInboxVibrate;
private Preference mInboxRingtone;
+ private Preference mPerFolderNotification;
private Context mContext;
private Handler mHandler;
@@ -307,9 +310,10 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
@NonNull Preference preference) {
final String key = preference.getKey();
- if (key.equals(PREFERENCE_SYNC_SETTINGS)) {
+ if (key.equals(PREFERENCE_SYNC_SETTINGS) ||
+ key.equals(PREFERENCE_PER_FOLDER_NOTIFICATIONS)) {
startActivity(MailboxSettings.getIntent(getActivity(), mUiAccount.fullFolderListUri,
- mInboxFolder));
+ mInboxFolder, key));
return true;
} else {
return super.onPreferenceTreeClick(preferenceScreen, preference);
@@ -847,43 +851,77 @@ public class AccountSettingsFragment extends MailAccountPrefsFragment
(PreferenceCategory) findPreference(PREFERENCE_CATEGORY_NOTIFICATIONS);
if (mInboxFolderPreferences != null) {
- final CheckBoxPreference inboxNotify = (CheckBoxPreference) findPreference(
- FolderPreferences.PreferenceKeys.NOTIFICATIONS_ENABLED);
- inboxNotify.setChecked(mInboxFolderPreferences.areNotificationsEnabled());
- inboxNotify.setOnPreferenceChangeListener(this);
-
- mInboxRingtone = findPreference(FolderPreferences.PreferenceKeys.NOTIFICATION_RINGTONE);
- final String ringtoneUri = mInboxFolderPreferences.getNotificationRingtoneUri();
- if (!TextUtils.isEmpty(ringtoneUri)) {
- mRingtone = RingtoneManager.getRingtone(getActivity(), Uri.parse(ringtoneUri));
- }
- setRingtoneSummary();
- mInboxRingtone.setOnPreferenceChangeListener(this);
- mInboxRingtone.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(final Preference preference) {
- showRingtonePicker();
+ if (mServiceInfo.offerLookback) {
+ // This account supports per-folder notifications
+
+ // Enable per-folder notifications preference
+ if (mPerFolderNotification == null) {
+ mPerFolderNotification = new Preference(mContext);
+ mPerFolderNotification.setKey(PREFERENCE_PER_FOLDER_NOTIFICATIONS);
+ notificationsCategory.addPreference(mPerFolderNotification);
+ }
+ mPerFolderNotification.setTitle(R.string.folder_notify_settings_pref_title);
- return true;
+ // Remove Inbox per-account preferences
+ final CheckBoxPreference inboxNotify = (CheckBoxPreference) findPreference(
+ FolderPreferences.PreferenceKeys.NOTIFICATIONS_ENABLED);
+ if (inboxNotify != null) {
+ notificationsCategory.removePreference(inboxNotify);
}
- });
-
- notificationsCategory.setEnabled(true);
-
- // Set the vibrator value, or hide it on devices w/o a vibrator
- mInboxVibrate = (CheckBoxPreference) findPreference(
- FolderPreferences.PreferenceKeys.NOTIFICATION_VIBRATE);
- if (mInboxVibrate != null) {
- mInboxVibrate.setChecked(
- mInboxFolderPreferences.isNotificationVibrateEnabled());
- Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
- if (vibrator.hasVibrator()) {
- // When the value is changed, update the setting.
- mInboxVibrate.setOnPreferenceChangeListener(this);
- } else {
- // No vibrator present. Remove the preference altogether.
+ mInboxRingtone = findPreference(
+ FolderPreferences.PreferenceKeys.NOTIFICATION_RINGTONE);
+ if (mInboxRingtone != null) {
+ notificationsCategory.removePreference(mInboxRingtone);
+ }
+ mInboxVibrate = (CheckBoxPreference) findPreference(
+ FolderPreferences.PreferenceKeys.NOTIFICATION_VIBRATE);
+ if (mInboxVibrate != null) {
notificationsCategory.removePreference(mInboxVibrate);
- mInboxVibrate = null;
+ }
+
+ notificationsCategory.setEnabled(true);
+
+ } else {
+ final CheckBoxPreference inboxNotify = (CheckBoxPreference) findPreference(
+ FolderPreferences.PreferenceKeys.NOTIFICATIONS_ENABLED);
+ inboxNotify.setChecked(mInboxFolderPreferences.areNotificationsEnabled());
+ inboxNotify.setOnPreferenceChangeListener(this);
+
+ mInboxRingtone = findPreference(
+ FolderPreferences.PreferenceKeys.NOTIFICATION_RINGTONE);
+ final String ringtoneUri = mInboxFolderPreferences.getNotificationRingtoneUri();
+ if (!TextUtils.isEmpty(ringtoneUri)) {
+ mRingtone = RingtoneManager.getRingtone(getActivity(), Uri.parse(ringtoneUri));
+ }
+ setRingtoneSummary();
+ mInboxRingtone.setOnPreferenceChangeListener(this);
+ mInboxRingtone.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(final Preference preference) {
+ showRingtonePicker();
+
+ return true;
+ }
+ });
+
+ notificationsCategory.setEnabled(true);
+
+ // Set the vibrator value, or hide it on devices w/o a vibrator
+ mInboxVibrate = (CheckBoxPreference) findPreference(
+ FolderPreferences.PreferenceKeys.NOTIFICATION_VIBRATE);
+ if (mInboxVibrate != null) {
+ mInboxVibrate.setChecked(
+ mInboxFolderPreferences.isNotificationVibrateEnabled());
+ Vibrator vibrator = (Vibrator) mContext.getSystemService(
+ Context.VIBRATOR_SERVICE);
+ if (vibrator.hasVibrator()) {
+ // When the value is changed, update the setting.
+ mInboxVibrate.setOnPreferenceChangeListener(this);
+ } else {
+ // No vibrator present. Remove the preference altogether.
+ notificationsCategory.removePreference(mInboxVibrate);
+ mInboxVibrate = null;
+ }
}
}
} else {
diff --git a/src/com/android/email/activity/setup/MailboxSettings.java b/src/com/android/email/activity/setup/MailboxSettings.java
index 42ae407dd..d6b649a36 100644
--- a/src/com/android/email/activity/setup/MailboxSettings.java
+++ b/src/com/android/email/activity/setup/MailboxSettings.java
@@ -17,6 +17,7 @@
package com.android.email.activity.setup;
import android.app.ActionBar;
+import android.app.Activity;
import android.app.LoaderManager;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -26,17 +27,29 @@ import android.content.Intent;
import android.content.Loader;
import android.content.res.Resources;
import android.database.Cursor;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Vibrator;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
+import android.provider.Settings;
import android.support.annotation.NonNull;
+import android.support.v4.util.Pair;
import android.text.TextUtils;
+import android.view.LayoutInflater;
import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
import com.android.email.R;
import com.android.emailcommon.Logging;
@@ -47,14 +60,18 @@ import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.provider.Policy;
import com.android.emailcommon.utility.EmailAsyncTask;
import com.android.emailcommon.utility.Utility;
+import com.android.mail.preferences.FolderPreferences;
import com.android.mail.providers.Folder;
import com.android.mail.providers.UIProvider;
import com.android.mail.ui.MailAsyncTaskLoader;
import com.android.mail.utils.LogUtils;
import com.google.common.base.Preconditions;
+import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -70,21 +87,30 @@ import java.util.Map;
* #onDestroy()}, unless it's called for configuration changes.
*/
public class MailboxSettings extends PreferenceActivity {
+ public static final String PREFERENCE_SYNC_SETTINGS = "account_sync_settings";
+ public static final String PREFERENCE_PER_FOLDER_NOTIFICATIONS =
+ "account_per_folder_notifications";
+
private static final String EXTRA_FOLDERS_URI = "FOLDERS_URI";
private static final String EXTRA_INBOX_ID = "INBOX_ID";
+ private static final String EXTRA_TYPE = "TYPE";
+
+ private static final String EXTRA_HEADER_FOLDER_INDENT = "folder-indent";
private static final int FOLDERS_LOADER_ID = 0;
private Uri mFoldersUri;
private int mInboxId;
- private final List<Folder> mFolders = new ArrayList<>();
+ private String mType;
+ private final List<Pair<Folder,String>> mFolders = new ArrayList<>();
/**
* Starts the activity
*/
- public static Intent getIntent(Context context, Uri foldersUri, Folder inbox) {
+ public static Intent getIntent(Context context, Uri foldersUri, Folder inbox, String type) {
final Intent i = new Intent(context, MailboxSettings.class);
i.putExtra(EXTRA_FOLDERS_URI, foldersUri);
i.putExtra(EXTRA_INBOX_ID, inbox.id);
+ i.putExtra(EXTRA_TYPE, type);
return i;
}
@@ -93,6 +119,7 @@ public class MailboxSettings extends PreferenceActivity {
// This needs to happen before super.onCreate() since that calls onBuildHeaders()
mInboxId = getIntent().getIntExtra(EXTRA_INBOX_ID, -1);
mFoldersUri = getIntent().getParcelableExtra(EXTRA_FOLDERS_URI);
+ mType = getIntent().getStringExtra(EXTRA_TYPE);
if (mFoldersUri != null) {
getLoaderManager().initLoader(FOLDERS_LOADER_ID, null,
@@ -108,6 +135,11 @@ public class MailboxSettings extends PreferenceActivity {
// Hide the app icon.
actionBar.setIcon(android.R.color.transparent);
actionBar.setDisplayUseLogoEnabled(false);
+ if (mType != null && mType.equals(PREFERENCE_SYNC_SETTINGS)) {
+ actionBar.setTitle(getString(R.string.mailbox_settings_activity_title));
+ } else if (mType != null && mType.equals(PREFERENCE_PER_FOLDER_NOTIFICATIONS)) {
+ actionBar.setTitle(getString(R.string.mailbox_notify_settings_activity_title));
+ }
}
}
@@ -117,25 +149,28 @@ public class MailboxSettings extends PreferenceActivity {
final Header dummy = new Header();
dummy.titleRes = R.string.mailbox_name_display_inbox;
dummy.fragment = MailboxSettingsFragment.class.getName();
- dummy.fragmentArguments = MailboxSettingsFragment.getArguments(mInboxId);
- target.add(dummy);
+ dummy.fragmentArguments = MailboxSettingsFragment.getArguments(mInboxId, null);
+
} else {
- for (final Folder f : mFolders) {
+ for (final Pair<Folder, String> f : mFolders) {
final Header h = new Header();
- if (!TextUtils.isEmpty(f.hierarchicalDesc)) {
- h.title = f.hierarchicalDesc;
- } else {
- h.title = f.name;
- }
- h.fragment = MailboxSettingsFragment.class.getName();
- h.fragmentArguments = MailboxSettingsFragment.getArguments(f.id);
- if (f.id == mInboxId) {
- target.add(0, h);
- } else {
- target.add(h);
+ h.title = f.first.name;
+ setMailboxHeaderIcon(h, f.first);
+ h.extras = new Bundle();
+ h.extras.putInt(EXTRA_HEADER_FOLDER_INDENT, f.second.split("\\/").length - 1);
+ if (mType != null && mType.equals(PREFERENCE_SYNC_SETTINGS)) {
+ h.fragment = MailboxSettingsFragment.class.getName();
+ h.fragmentArguments = MailboxSettingsFragment.getArguments(f.first.id, mType);
+ } else if (mType != null && mType.equals(PREFERENCE_PER_FOLDER_NOTIFICATIONS)) {
+ h.fragment = MailboxNotificationsFragment.class.getName();
+ h.fragmentArguments = MailboxNotificationsFragment.getArguments(
+ f.first, mType);
}
+ target.add(h);
}
}
+
+ setListAdapter(new MailboxHeadersAdapter(this, target));
}
@Override
@@ -153,6 +188,17 @@ public class MailboxSettings extends PreferenceActivity {
return super.onOptionsItemSelected(item);
}
+ private void setMailboxHeaderIcon(Header header, Folder folder) {
+ if (folder.isSent()) {
+ header.iconRes = R.drawable.ic_drawer_sent_24dp;
+ } else if (folder.isInbox()) {
+ header.iconRes = R.drawable.ic_drawer_inbox_24dp;
+ } else {
+ header.iconRes = folder.hasChildren ? R.drawable.ic_folder_parent_24dp
+ : R.drawable.ic_drawer_folder_24dp;
+ }
+ }
+
/**
* Setup the entries and entry values for the sync lookback preference
* @param context the caller's context
@@ -190,6 +236,49 @@ public class MailboxSettings extends PreferenceActivity {
pref.setSummary(pref.getEntry());
}
+ private static class MailboxHeadersAdapter extends ArrayAdapter<Header> {
+ private static class HeaderViewHolder {
+ View spacer;
+ ImageView icon;
+ TextView title;
+ }
+
+ private LayoutInflater mInflater;
+ private int mFolderIndent;
+
+ public MailboxHeadersAdapter(Context context, List<Header> objects) {
+ super(context, 0, objects);
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mFolderIndent = (int) context.getResources().getDimension(R.dimen.child_folder_indent);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ HeaderViewHolder holder;
+ View view;
+
+ if (convertView == null) {
+ view = mInflater.inflate(R.layout.preference_mailbox_item, parent, false);
+ holder = new HeaderViewHolder();
+ holder.spacer = view.findViewById(R.id.spacer);
+ holder.icon = (ImageView) view.findViewById(R.id.icon);
+ holder.title = (TextView) view.findViewById(android.R.id.title);
+ view.setTag(holder);
+ } else {
+ view = convertView;
+ holder = (HeaderViewHolder) view.getTag();
+ }
+
+ // All view fields must be updated every time, because the view may be recycled
+ Header header = getItem(position);
+ int headerIndent = header.extras.getInt(EXTRA_HEADER_FOLDER_INDENT, 0);
+ holder.spacer.getLayoutParams().width = mFolderIndent * headerIndent;
+ holder.icon.setImageResource(header.iconRes);
+ holder.title.setText(header.getTitle(getContext().getResources()));
+ return view;
+ }
+ }
+
private class MailboxSettingsFolderLoaderCallbacks
implements LoaderManager.LoaderCallbacks<Cursor> {
@@ -206,14 +295,69 @@ public class MailboxSettings extends PreferenceActivity {
}
mFolders.clear();
+ // Convert the cursor to an temp array and map all the folders
+ Map<Uri, Folder> folders = new HashMap<>();
+ List<Folder> tmp = new ArrayList<>();
+ Folder inbox = null;
+ Folder sent = null;
while(cursor.moveToNext()) {
final Folder folder = new Folder(cursor);
if (!folder.supportsCapability(UIProvider.FolderCapabilities.IS_VIRTUAL) &&
!folder.isTrash() && !folder.isDraft() && !folder.isOutbox()) {
- mFolders.add(folder);
+ if (folder.id == mInboxId) {
+ inbox = folder;
+ } else if (folder.isSent()) {
+ sent = folder;
+ }
+ tmp.add(folder);
+ folders.put(folder.folderUri.fullUri, folder);
}
}
+ // Create the hierarchical paths of all the folders
+ int count = tmp.size();
+ for (int i = 0; i < count; i++) {
+ Folder folder = tmp.get(i);
+ mFolders.add(new Pair<Folder, String>(folder,
+ getHierarchicalFolder(folder, folders)));
+ }
+
+ // Sort folders by hierarchical path
+ final String inboxFolderName = inbox.name;
+ final String sentFolderName = sent.name;
+ Collections.sort(mFolders, new Comparator<Pair<Folder, String>>() {
+ private final Collator mCollator = Collator.getInstance();
+ @Override
+ public int compare(Pair<Folder, String> lhs, Pair<Folder, String> rhs) {
+ boolean lInbox = lhs.second.startsWith(inboxFolderName);
+ boolean rInbox = rhs.second.startsWith(inboxFolderName);
+ boolean lSent = lhs.second.startsWith(sentFolderName);
+ boolean rSent = rhs.second.startsWith(sentFolderName);
+ String lParent = getHierarchicalParentFolder(lhs.second);
+ String rParent = getHierarchicalParentFolder(rhs.second);
+ if (lInbox && !rInbox) {
+ return -1;
+ } else if (!lInbox && rInbox) {
+ return 1;
+ }
+ if (lSent && !rSent) {
+ return -1;
+ } else if (!lSent && rSent) {
+ return 1;
+ }
+ if (lhs.second.startsWith(rhs.second)) {
+ return 1;
+ }
+ if (rhs.second.startsWith(lhs.second)) {
+ return -1;
+ }
+ if (lParent != null && rParent != null && lParent.equals(rParent)) {
+ return mCollator.compare(lhs.first.name, rhs.first.name);
+ }
+ return mCollator.compare(lhs.second, rhs.second);
+ }
+ });
+
invalidateHeaders();
}
@@ -221,6 +365,344 @@ public class MailboxSettings extends PreferenceActivity {
public void onLoaderReset(Loader<Cursor> cursorLoader) {
mFolders.clear();
}
+
+ private String getHierarchicalFolder(Folder folder, Map<Uri, Folder> folders) {
+ if (!TextUtils.isEmpty(folder.hierarchicalDesc)) {
+ return folder.hierarchicalDesc;
+ }
+ String name = folder.name;
+ Folder tmp = folder;
+ while (tmp != null && tmp.parent != null && !tmp.parent.toString().isEmpty()) {
+ tmp = folders.get(tmp.parent);
+ name = tmp.name + "/" + name;
+ }
+ return name;
+ }
+
+ private String getHierarchicalParentFolder(String folder) {
+ int pos = folder.lastIndexOf("/");
+ if (pos != -1) {
+ return folder.substring(0, pos);
+ }
+ return null;
+ }
+ }
+
+ public static class MailboxNotificationsFragment extends PreferenceFragment {
+ private static final String EXTRA_MAILBOX_ID = "MailboxId";
+ private static final String EXTRA_MAILBOX_PERSISTEND_ID = "MailboxPersistentId";
+ private static final String EXTRA_MAILBOX_IS_INBOX = "MailboxIsInbox";
+
+ private static final String BUNDLE_ACCOUNT = "MailboxNotifySettings.account";
+ private static final String BUNDLE_MAILBOX = "MailboxNotifySettings.mailbox";
+ private static final String BUNDLE_NOTIF_ENABLED = "MailboxNotifySettings.enabled";
+ private static final String BUNDLE_NOTIF_RINGTONE = "MailboxSettings.ringtone";
+ private static final String BUNDLE_NOTIF_VIBRATE = "MailboxSettings.vibrate";
+
+ private static final String PREF_NOTIF_ENABLED_KEY = "notifications-enabled";
+ private static final String PREF_NOTIF_RINGTONE_KEY = "notification-ringtone";
+ private static final String PREF_NOTIF_VIBRATE_KEY = "notification-vibrate";
+
+ private static final int RINGTONE_REQUEST_CODE =
+ MailboxNotificationsFragment.class.hashCode();
+
+ private FolderPreferences mPreferences;
+ private Account mAccount;
+ private Mailbox mMailbox;
+
+ private CheckBoxPreference mPrefNotifEnabled;
+ private Preference mPrefNotifRingtone;
+ private CheckBoxPreference mPrefNotifVibrate;
+
+ private boolean mOldMailboxEnabled;
+ private String mOldMailboxRingtone;
+ private boolean mOldMailboxVibrate;
+
+ private Uri mRingtoneUri;
+ private Ringtone mRingtone;
+
+ private static Bundle getArguments(Folder folder, String type) {
+ final Bundle b = new Bundle(4);
+ b.putLong(EXTRA_MAILBOX_ID, folder.id);
+ b.putString(EXTRA_MAILBOX_PERSISTEND_ID, folder.persistentId);
+ b.putBoolean(EXTRA_MAILBOX_IS_INBOX, folder.isInbox());
+ b.putString(EXTRA_TYPE, type);
+ return b;
+ }
+
+ public MailboxNotificationsFragment() {}
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ final long mailboxId = getArguments().getLong(EXTRA_MAILBOX_ID, Mailbox.NO_MAILBOX);
+ final String mailboxPersistenId = getArguments().getString(
+ EXTRA_MAILBOX_PERSISTEND_ID, null);
+ final boolean mailboxIsInbox = getArguments().getBoolean(EXTRA_MAILBOX_IS_INBOX, false);
+ if (mailboxId == Mailbox.NO_MAILBOX || mailboxPersistenId == null) {
+ getActivity().finish();
+ }
+
+ addPreferencesFromResource(R.xml.mailbox_notifications_preferences);
+
+ mPrefNotifEnabled = (CheckBoxPreference) findPreference(PREF_NOTIF_ENABLED_KEY);
+ mPrefNotifRingtone = findPreference(PREF_NOTIF_RINGTONE_KEY);
+ mPrefNotifRingtone.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ showRingtonePicker();
+ return true;
+ }
+ });
+ mPrefNotifVibrate = (CheckBoxPreference) findPreference(PREF_NOTIF_VIBRATE_KEY);
+ Vibrator vibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
+ if (!vibrator.hasVibrator()) {
+ mPrefNotifVibrate.setChecked(false);
+ getPreferenceScreen().removePreference(mPrefNotifVibrate);
+ mPrefNotifVibrate = null;
+ }
+
+ if (savedInstanceState != null) {
+ mAccount = savedInstanceState.getParcelable(BUNDLE_ACCOUNT);
+ mMailbox = savedInstanceState.getParcelable(BUNDLE_MAILBOX);
+ mPreferences = new FolderPreferences(getActivity(), mAccount.mEmailAddress,
+ mailboxPersistenId, mailboxIsInbox);
+
+ mPrefNotifEnabled.setChecked(savedInstanceState.getBoolean(BUNDLE_NOTIF_ENABLED));
+ setRingtone(savedInstanceState.getString(BUNDLE_NOTIF_RINGTONE));
+ if (mPrefNotifVibrate != null) {
+ mPrefNotifVibrate.setChecked(
+ savedInstanceState.getBoolean(BUNDLE_NOTIF_VIBRATE));
+ }
+ onDataLoaded();
+ } else {
+ // Make them disabled until we load data
+ enablePreferences(false);
+ getLoaderManager().initLoader(0, getArguments(), new MailboxLoaderCallbacks());
+ }
+ }
+
+ private void setRingtone(String ringtone) {
+ if (!TextUtils.isEmpty(ringtone)) {
+ mRingtoneUri = Uri.parse(ringtone);
+ mRingtone = RingtoneManager.getRingtone(getActivity(), mRingtoneUri);
+ } else {
+ mRingtoneUri = null;
+ mRingtone = null;
+ }
+ setRingtoneSummary();
+ }
+
+ private void setRingtoneSummary() {
+ final String summary = mRingtone != null ? mRingtone.getTitle(getActivity())
+ : getString(R.string.silent_ringtone);
+ mPrefNotifRingtone.setSummary(summary);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == RINGTONE_REQUEST_CODE) {
+ if (resultCode == Activity.RESULT_OK && data != null) {
+ Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
+ String ringtone = "";
+ if (uri != null) {
+ ringtone = uri.toString();
+ }
+ setRingtone(ringtone);
+ }
+ }
+ }
+
+ private void enablePreferences(boolean enabled) {
+ mPrefNotifEnabled.setEnabled(enabled);
+ mPrefNotifRingtone.setEnabled(enabled);
+ if (mPrefNotifVibrate != null) {
+ mPrefNotifVibrate.setEnabled(enabled);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putParcelable(BUNDLE_ACCOUNT, mAccount);
+ outState.putParcelable(BUNDLE_MAILBOX, mMailbox);
+ outState.putBoolean(BUNDLE_NOTIF_ENABLED, mPrefNotifEnabled.isChecked());
+ String ringtoneUri = "";
+ if (mRingtoneUri != null) {
+ ringtoneUri = mRingtoneUri.toString();
+ }
+ outState.putString(BUNDLE_NOTIF_RINGTONE, ringtoneUri);
+ outState.putBoolean(PREF_NOTIF_VIBRATE_KEY, mPrefNotifVibrate != null
+ ? mPrefNotifVibrate.isChecked() : false);
+ }
+
+ /**
+ * We save all the settings in onDestroy, *unless it's for configuration changes*.
+ */
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (!getActivity().isChangingConfigurations()) {
+ savePreferences();
+ }
+ }
+
+ private void loadOldPreferencesValues() {
+ mOldMailboxEnabled = mPreferences.areNotificationsEnabled();
+ mOldMailboxRingtone = mPreferences.getNotificationRingtoneUri();
+ mOldMailboxVibrate = mPreferences.isNotificationVibrateEnabled();
+ }
+
+ /**
+ * Shows the system ringtone picker.
+ */
+ private void showRingtonePicker() {
+ Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
+ final String ringtoneUri = mPreferences.getNotificationRingtoneUri();
+ if (!TextUtils.isEmpty(ringtoneUri)) {
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI,
+ Uri.parse(ringtoneUri));
+ }
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI,
+ Settings.System.DEFAULT_NOTIFICATION_URI);
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
+ RingtoneManager.TYPE_NOTIFICATION);
+ startActivityForResult(intent, RINGTONE_REQUEST_CODE);
+ }
+
+ /**
+ * Called when {@link #mMailbox} is loaded (either by the loader or from the saved state).
+ */
+ private void onDataLoaded() {
+ Preconditions.checkNotNull(mAccount);
+ Preconditions.checkNotNull(mMailbox);
+
+ // Update the title with the mailbox name.
+ final ActionBar actionBar = getActivity().getActionBar();
+ final String mailboxName = mMailbox.mDisplayName;
+ if (actionBar != null) {
+ actionBar.setTitle(mailboxName);
+ actionBar.setSubtitle(getString(R.string.mailbox_notify_settings_activity_title));
+ } else {
+ getActivity().setTitle(
+ getString(R.string.mailbox_notify_settings_activity_title_with_mailbox,
+ mailboxName));
+ }
+ }
+
+ /**
+ * Save changes to the preferences folder backend.
+ *
+ * Note it's called from {@link #onDestroy()}
+ */
+ private void savePreferences() {
+ if (mPreferences == null) {
+ return;
+ }
+
+ boolean mailboxEnabled = mPrefNotifEnabled.isChecked();
+ String mailboxRingtone = "";
+ if (mRingtoneUri != null) {
+ mailboxRingtone = mRingtoneUri.toString();
+ }
+ boolean mailboxVibrate = mPrefNotifVibrate != null
+ ? mPrefNotifVibrate.isChecked() : false;
+ if (mailboxEnabled != mOldMailboxEnabled) {
+ mPreferences.setNotificationsEnabled(mailboxEnabled);
+ mOldMailboxEnabled = mailboxEnabled;
+ }
+ if (!mailboxRingtone.equals(mOldMailboxRingtone)) {
+ mPreferences.setNotificationRingtoneUri(mailboxRingtone);
+ mOldMailboxRingtone = mailboxRingtone;
+ }
+ if (mailboxVibrate != mOldMailboxVibrate) {
+ mPreferences.setNotificationVibrateEnabled(mailboxVibrate);
+ mOldMailboxVibrate = mailboxVibrate;
+ }
+ }
+
+ private static class MailboxLoader extends MailAsyncTaskLoader<Map<String, Object>> {
+
+ public static final String RESULT_KEY_MAILBOX = "mailbox";
+ public static final String RESULT_KEY_ACCOUNT = "account";
+
+ private final long mMailboxId;
+
+ private MailboxLoader(Context context, long mailboxId) {
+ super(context);
+ mMailboxId = mailboxId;
+ }
+
+ @Override
+ public Map<String, Object> loadInBackground() {
+ final Map<String, Object> result = new HashMap<>();
+
+ final Mailbox mailbox = Mailbox.restoreMailboxWithId(getContext(), mMailboxId);
+ if (mailbox == null) {
+ return null;
+ }
+ Account account = Account.restoreAccountWithId(getContext(), mailbox.mAccountKey);
+ if (account == null) {
+ return null;
+ }
+ result.put(RESULT_KEY_MAILBOX, mailbox);
+ result.put(RESULT_KEY_ACCOUNT, account);
+ return result;
+ }
+
+ @Override
+ protected void onDiscardResult(Map<String, Object> result) {}
+ }
+
+ private class MailboxLoaderCallbacks
+ implements LoaderManager.LoaderCallbacks<Map<String, Object>> {
+
+ private long mMailboxId;
+ private String mMailboxPersistentId;
+ private boolean mMailboxIsInbox;
+
+ @Override
+ public Loader<Map<String, Object>> onCreateLoader(int id, Bundle args) {
+ mMailboxId = getArguments().getLong(EXTRA_MAILBOX_ID, Mailbox.NO_MAILBOX);
+ mMailboxPersistentId = getArguments().getString(EXTRA_MAILBOX_PERSISTEND_ID, null);
+ mMailboxIsInbox = getArguments().getBoolean(EXTRA_MAILBOX_IS_INBOX, false);
+ return new MailboxLoader(getActivity(), mMailboxId);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Map<String, Object>> loader,
+ Map<String, Object> data) {
+ final Mailbox mailbox = (Mailbox) (data == null
+ ? null : data.get(MailboxLoader.RESULT_KEY_MAILBOX));
+ final Account account = (Account) (data == null
+ ? null : data.get(MailboxLoader.RESULT_KEY_ACCOUNT));
+ if (mailbox == null || account == null) {
+ getActivity().finish();
+ return;
+ }
+
+ mAccount = account;
+ mMailbox = mailbox;
+ mPreferences = new FolderPreferences(getActivity(), mAccount.mEmailAddress,
+ mMailboxPersistentId, mMailboxIsInbox);
+ loadOldPreferencesValues();
+
+ mPrefNotifEnabled.setChecked(mPreferences.areNotificationsEnabled());
+ setRingtone(mPreferences.getNotificationRingtoneUri());
+ if (mPrefNotifVibrate != null) {
+ mPrefNotifVibrate.setChecked(mPreferences.isNotificationVibrateEnabled());
+ }
+ onDataLoaded();
+ if (mMailbox.mType != Mailbox.TYPE_DRAFTS) {
+ enablePreferences(true);
+ }
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Map<String, Object>> loader) {}
+ }
}
public static class MailboxSettingsFragment extends PreferenceFragment {
@@ -241,9 +723,10 @@ public class MailboxSettings extends PreferenceActivity {
private CheckBoxPreference mSyncEnabledPref;
private ListPreference mSyncLookbackPref;
- private static Bundle getArguments(long mailboxId) {
+ private static Bundle getArguments(long mailboxId, String type) {
final Bundle b = new Bundle(1);
b.putLong(EXTRA_MAILBOX_ID, mailboxId);
+ b.putString(EXTRA_TYPE, type);
return b;
}