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>
This commit is contained in:
Jorge Ruesga 2015-04-04 20:42:30 +02:00 committed by Steve Kondik
parent 598a070c27
commit 707cdc8b18
6 changed files with 697 additions and 54 deletions

View File

@ -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>

20
res/values/cm_dimens.xml Normal file
View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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);
if (mServiceInfo.offerLookback) {
// This account supports per-folder notifications
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;
// 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);
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.
// Remove Inbox per-account preferences
final CheckBoxPreference inboxNotify = (CheckBoxPreference) findPreference(
FolderPreferences.PreferenceKeys.NOTIFICATIONS_ENABLED);
if (inboxNotify != null) {
notificationsCategory.removePreference(inboxNotify);
}
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 {

View File

@ -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;
}