mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-30 13:12:25 -05:00
Merge remote branch 'upstream/master'
This commit is contained in:
commit
5e3dbdcc11
@ -19,7 +19,9 @@ import com.fsck.k9.K9;
|
|||||||
|
|
||||||
|
|
||||||
public class K9Activity extends Activity {
|
public class K9Activity extends Activity {
|
||||||
private GestureDetector gestureDetector;
|
protected static final int BEZEL_SWIPE_THRESHOLD = 20;
|
||||||
|
|
||||||
|
protected GestureDetector mGestureDetector;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
@ -27,10 +29,6 @@ public class K9Activity extends Activity {
|
|||||||
setTheme(K9.getK9ThemeResourceId());
|
setTheme(K9.getK9ThemeResourceId());
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
setupFormats();
|
setupFormats();
|
||||||
|
|
||||||
// Gesture detection
|
|
||||||
gestureDetector = new GestureDetector(new MyGestureDetector());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setLanguage(Context context, String language) {
|
public static void setLanguage(Context context, String language) {
|
||||||
@ -51,8 +49,10 @@ public class K9Activity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||||
super.dispatchTouchEvent(ev);
|
if (mGestureDetector != null) {
|
||||||
return gestureDetector.onTouchEvent(ev);
|
mGestureDetector.onTouchEvent(ev);
|
||||||
|
}
|
||||||
|
return super.dispatchTouchEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -184,6 +184,10 @@ public class K9Activity extends Activity {
|
|||||||
Log.d(K9.LOG_TAG, "New swipe algorithm: Swipe did not meet minimum distance requirements.");
|
Log.d(K9.LOG_TAG, "New swipe algorithm: Swipe did not meet minimum distance requirements.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// successful fling, cancel the 2nd event to prevent any other action from happening
|
||||||
|
// see http://code.google.com/p/android/issues/detail?id=8497
|
||||||
|
e2.setAction(MotionEvent.ACTION_CANCEL);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
@ -690,6 +690,9 @@ public class MessageList
|
|||||||
mPreviewLines = K9.messageListPreviewLines();
|
mPreviewLines = K9.messageListPreviewLines();
|
||||||
|
|
||||||
initializeMessageList(getIntent(), true);
|
initializeMessageList(getIntent(), true);
|
||||||
|
|
||||||
|
// Enable gesture detection for MessageLists
|
||||||
|
mGestureDetector = new GestureDetector(new MyGestureDetector(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -924,20 +927,6 @@ public class MessageList
|
|||||||
mBatchMoveButton.setVisibility(K9.batchButtonsMove() ? View.VISIBLE : View.GONE);
|
mBatchMoveButton.setVisibility(K9.batchButtonsMove() ? View.VISIBLE : View.GONE);
|
||||||
mBatchFlagButton.setVisibility(K9.batchButtonsFlag() ? View.VISIBLE : View.GONE);
|
mBatchFlagButton.setVisibility(K9.batchButtonsFlag() ? View.VISIBLE : View.GONE);
|
||||||
mBatchDoneButton.setVisibility(K9.batchButtonsUnselect() ? View.VISIBLE : View.GONE);
|
mBatchDoneButton.setVisibility(K9.batchButtonsUnselect() ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
// Gesture detection
|
|
||||||
gestureDetector = new GestureDetector(new MyGestureDetector(true));
|
|
||||||
gestureListener = new View.OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
if (gestureDetector.onTouchEvent(event)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mListView.setOnTouchListener(gestureListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1807,7 +1796,9 @@ public class MessageList
|
|||||||
* @param selected true if this was an attempt to select (i.e. left to right).
|
* @param selected true if this was an attempt to select (i.e. left to right).
|
||||||
*/
|
*/
|
||||||
private void handleSwipe(final MotionEvent downMotion, final boolean selected) {
|
private void handleSwipe(final MotionEvent downMotion, final boolean selected) {
|
||||||
int position = mListView.pointToPosition((int) downMotion.getX(), (int) downMotion.getY());
|
int[] listPosition = new int[2];
|
||||||
|
mListView.getLocationOnScreen(listPosition);
|
||||||
|
int position = mListView.pointToPosition((int) downMotion.getRawX() - listPosition[0], (int) downMotion.getRawY() - listPosition[1]);
|
||||||
if (position != AdapterView.INVALID_POSITION) {
|
if (position != AdapterView.INVALID_POSITION) {
|
||||||
MessageInfoHolder msgInfoHolder = (MessageInfoHolder) mAdapter.getItem(position);
|
MessageInfoHolder msgInfoHolder = (MessageInfoHolder) mAdapter.getItem(position);
|
||||||
|
|
||||||
|
@ -81,6 +81,18 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
*/
|
*/
|
||||||
private Bundle mMessageListExtras;
|
private Bundle mMessageListExtras;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Screen width in pixels.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Used to detect right-to-left bezel swipes.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #onSwipeRightToLeft(MotionEvent, MotionEvent)
|
||||||
|
*/
|
||||||
|
private int mScreenWidthInPixels;
|
||||||
|
|
||||||
|
|
||||||
private final class StorageListenerImplementation implements StorageManager.StorageListener {
|
private final class StorageListenerImplementation implements StorageManager.StorageListener {
|
||||||
@Override
|
@Override
|
||||||
public void onUnmount(String providerId) {
|
public void onUnmount(String providerId) {
|
||||||
@ -379,6 +391,11 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
mNext.requestFocus();
|
mNext.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mScreenWidthInPixels = getResources().getDisplayMetrics().widthPixels;
|
||||||
|
|
||||||
|
// Enable gesture detection for MessageViews
|
||||||
|
mGestureDetector = new GestureDetector(new MyGestureDetector(false));
|
||||||
|
|
||||||
setupButtonViews();
|
setupButtonViews();
|
||||||
displayMessage(mMessageReference);
|
displayMessage(mMessageReference);
|
||||||
}
|
}
|
||||||
@ -711,20 +728,25 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a right-to-left swipe as "move to next message."
|
* Handle a right-to-left swipe starting at the edge of the screen as "move to next message."
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void onSwipeRightToLeft(MotionEvent e1, MotionEvent e2) {
|
protected void onSwipeRightToLeft(MotionEvent e1, MotionEvent e2) {
|
||||||
|
if ((int) e1.getRawX() > mScreenWidthInPixels - BEZEL_SWIPE_THRESHOLD) {
|
||||||
onNext();
|
onNext();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a left-to-right swipe as "move to previous message."
|
* Handle a left-to-right swipe starting at the edge of the screen as
|
||||||
|
* "move to previous message."
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void onSwipeLeftToRight(MotionEvent e1, MotionEvent e2) {
|
protected void onSwipeLeftToRight(MotionEvent e1, MotionEvent e2) {
|
||||||
|
if ((int) e1.getRawX() < BEZEL_SWIPE_THRESHOLD) {
|
||||||
onPrevious();
|
onPrevious();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void onNext() {
|
protected void onNext() {
|
||||||
// Reset scroll percentage when we change messages
|
// Reset scroll percentage when we change messages
|
||||||
|
@ -16,12 +16,10 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
@ -38,6 +36,7 @@ import com.fsck.k9.SearchSpecification;
|
|||||||
import com.fsck.k9.K9.Intents;
|
import com.fsck.k9.K9.Intents;
|
||||||
import com.fsck.k9.activity.FolderList;
|
import com.fsck.k9.activity.FolderList;
|
||||||
import com.fsck.k9.activity.MessageList;
|
import com.fsck.k9.activity.MessageList;
|
||||||
|
import com.fsck.k9.helper.NotificationBuilder;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.helper.power.TracingPowerManager;
|
import com.fsck.k9.helper.power.TracingPowerManager;
|
||||||
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
|
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
|
||||||
@ -2997,80 +2996,139 @@ public class MessagingController implements Runnable {
|
|||||||
|
|
||||||
private void cancelNotification(int id) {
|
private void cancelNotification(int id) {
|
||||||
NotificationManager notifMgr =
|
NotificationManager notifMgr =
|
||||||
(NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
(NotificationManager) mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
notifMgr.cancel(id);
|
notifMgr.cancel(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyWhileSendingDone(Account account) {
|
private void notifyWhileSendingDone(Account account) {
|
||||||
if (account.isShowOngoing()) {
|
if (account.isShowOngoing()) {
|
||||||
cancelNotification(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber());
|
cancelNotification(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display an ongoing notification while a message is being sent.
|
||||||
|
*
|
||||||
|
* @param account
|
||||||
|
* The account the message is sent from. Never {@code null}.
|
||||||
|
*/
|
||||||
private void notifyWhileSending(Account account) {
|
private void notifyWhileSending(Account account) {
|
||||||
if (!account.isShowOngoing()) {
|
if (!account.isShowOngoing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationManager notifMgr =
|
NotificationManager notifMgr =
|
||||||
(NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
(NotificationManager) mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
Notification notif = new Notification(R.drawable.ic_menu_refresh,
|
|
||||||
mApplication.getString(R.string.notification_bg_send_ticker, account.getDescription()), System.currentTimeMillis());
|
NotificationBuilder builder = NotificationBuilder.getInstance(mApplication);
|
||||||
Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, account.getInboxFolderName());
|
builder.setSmallIcon(R.drawable.ic_menu_refresh);
|
||||||
|
builder.setWhen(System.currentTimeMillis());
|
||||||
|
builder.setOngoing(true);
|
||||||
|
builder.setTicker(mApplication.getString(R.string.notification_bg_send_ticker,
|
||||||
|
account.getDescription()));
|
||||||
|
|
||||||
|
builder.setContentTitle(mApplication.getString(R.string.notification_bg_send_title));
|
||||||
|
builder.setContentText(account.getDescription());
|
||||||
|
|
||||||
|
Intent intent = MessageList.actionHandleFolderIntent(mApplication, account,
|
||||||
|
account.getInboxFolderName());
|
||||||
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0);
|
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0);
|
||||||
notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_send_title),
|
builder.setContentIntent(pi);
|
||||||
account.getDescription() , pi);
|
|
||||||
notif.flags = Notification.FLAG_ONGOING_EVENT;
|
|
||||||
|
|
||||||
if (K9.NOTIFICATION_LED_WHILE_SYNCING) {
|
if (K9.NOTIFICATION_LED_WHILE_SYNCING) {
|
||||||
configureNotification(notif, null, null, account.getNotificationSetting().getLedColor(), K9.NOTIFICATION_LED_BLINK_FAST, true);
|
configureNotification(builder, null, null,
|
||||||
|
account.getNotificationSetting().getLedColor(),
|
||||||
|
K9.NOTIFICATION_LED_BLINK_FAST, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(), notif);
|
notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(),
|
||||||
|
builder.getNotification());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifySendTempFailed(Account account, Exception lastFailure) {
|
private void notifySendTempFailed(Account account, Exception lastFailure) {
|
||||||
notifySendFailed(account, lastFailure, account.getOutboxFolderName());
|
notifySendFailed(account, lastFailure, account.getOutboxFolderName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifySendPermFailed(Account account, Exception lastFailure) {
|
private void notifySendPermFailed(Account account, Exception lastFailure) {
|
||||||
notifySendFailed(account, lastFailure, account.getDraftsFolderName());
|
notifySendFailed(account, lastFailure, account.getDraftsFolderName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a notification when sending a message has failed.
|
||||||
|
*
|
||||||
|
* @param account
|
||||||
|
* The account that was used to sent the message.
|
||||||
|
* @param lastFailure
|
||||||
|
* The {@link Exception} instance that indicated sending the message has failed.
|
||||||
|
* @param openFolder
|
||||||
|
* The name of the folder to open when the notification is clicked.
|
||||||
|
*/
|
||||||
private void notifySendFailed(Account account, Exception lastFailure, String openFolder) {
|
private void notifySendFailed(Account account, Exception lastFailure, String openFolder) {
|
||||||
NotificationManager notifMgr = (NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager notifMgr =
|
||||||
Notification notif = new Notification(R.drawable.stat_notify_email_generic, mApplication.getString(R.string.send_failure_subject), System.currentTimeMillis());
|
(NotificationManager) mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
NotificationBuilder builder = NotificationBuilder.getInstance(mApplication);
|
||||||
|
builder.setSmallIcon(R.drawable.stat_notify_email_generic);
|
||||||
|
builder.setWhen(System.currentTimeMillis());
|
||||||
|
builder.setAutoCancel(true);
|
||||||
|
builder.setTicker(mApplication.getString(R.string.send_failure_subject));
|
||||||
|
builder.setContentTitle(mApplication.getString(R.string.send_failure_subject));
|
||||||
|
builder.setContentText(getRootCauseMessage(lastFailure));
|
||||||
|
|
||||||
Intent i = FolderList.actionHandleNotification(mApplication, account, openFolder);
|
Intent i = FolderList.actionHandleNotification(mApplication, account, openFolder);
|
||||||
|
|
||||||
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, i, 0);
|
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, i, 0);
|
||||||
|
builder.setContentIntent(pi);
|
||||||
|
|
||||||
notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.send_failure_subject), getRootCauseMessage(lastFailure), pi);
|
configureNotification(builder, null, null, K9.NOTIFICATION_LED_SENDING_FAILURE_COLOR,
|
||||||
|
K9.NOTIFICATION_LED_BLINK_FAST, true);
|
||||||
|
|
||||||
configureNotification(notif, null, null, K9.NOTIFICATION_LED_SENDING_FAILURE_COLOR, K9.NOTIFICATION_LED_BLINK_FAST, true);
|
notifMgr.notify(K9.SEND_FAILED_NOTIFICATION - account.getAccountNumber(),
|
||||||
notif.flags |= Notification.FLAG_AUTO_CANCEL;
|
builder.getNotification());
|
||||||
notifMgr.notify(K9.SEND_FAILED_NOTIFICATION - account.getAccountNumber(), notif);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display an ongoing notification while checking for new messages on the server.
|
||||||
|
*
|
||||||
|
* @param account
|
||||||
|
* The account that is checked for new messages. Never {@code null}.
|
||||||
|
* @param folder
|
||||||
|
* The folder that is being checked for new messages. Never {@code null}.
|
||||||
|
*/
|
||||||
private void notifyFetchingMail(final Account account, final Folder folder) {
|
private void notifyFetchingMail(final Account account, final Folder folder) {
|
||||||
if (account.isShowOngoing()) {
|
if (!account.isShowOngoing()) {
|
||||||
final NotificationManager notifMgr = (NotificationManager)mApplication
|
return;
|
||||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
}
|
||||||
Notification notif = new Notification(R.drawable.ic_menu_refresh,
|
|
||||||
mApplication.getString(R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName()),
|
final NotificationManager notifMgr =
|
||||||
System.currentTimeMillis());
|
(NotificationManager) mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, account.getInboxFolderName());
|
|
||||||
|
NotificationBuilder builder = NotificationBuilder.getInstance(mApplication);
|
||||||
|
builder.setSmallIcon(R.drawable.ic_menu_refresh);
|
||||||
|
builder.setWhen(System.currentTimeMillis());
|
||||||
|
builder.setOngoing(true);
|
||||||
|
builder.setTicker(mApplication.getString(
|
||||||
|
R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName()));
|
||||||
|
builder.setContentTitle(mApplication.getString(R.string.notification_bg_sync_title));
|
||||||
|
builder.setContentText(account.getDescription() +
|
||||||
|
mApplication.getString(R.string.notification_bg_title_separator) +
|
||||||
|
folder.getName());
|
||||||
|
|
||||||
|
Intent intent = MessageList.actionHandleFolderIntent(mApplication, account,
|
||||||
|
account.getInboxFolderName());
|
||||||
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0);
|
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0);
|
||||||
notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_sync_title), account.getDescription()
|
builder.setContentIntent(pi);
|
||||||
+ mApplication.getString(R.string.notification_bg_title_separator) + folder.getName(), pi);
|
|
||||||
notif.flags = Notification.FLAG_ONGOING_EVENT;
|
|
||||||
|
|
||||||
if (K9.NOTIFICATION_LED_WHILE_SYNCING) {
|
if (K9.NOTIFICATION_LED_WHILE_SYNCING) {
|
||||||
configureNotification(notif, null, null, account.getNotificationSetting().getLedColor(), K9.NOTIFICATION_LED_BLINK_FAST, true);
|
configureNotification(builder, null, null,
|
||||||
|
account.getNotificationSetting().getLedColor(),
|
||||||
|
K9.NOTIFICATION_LED_BLINK_FAST, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(), notif);
|
notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(),
|
||||||
}
|
builder.getNotification());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyFetchingMailCancel(final Account account) {
|
private void notifyFetchingMailCancel(final Account account) {
|
||||||
if (account.isShowOngoing()) {
|
if (account.isShowOngoing()) {
|
||||||
cancelNotification(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber());
|
cancelNotification(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber());
|
||||||
@ -4126,22 +4184,31 @@ public class MessagingController implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NotificationManager notifMgr =
|
NotificationManager notifMgr =
|
||||||
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
Notification notif = new Notification(R.drawable.stat_notify_email_generic, messageNotice, System.currentTimeMillis());
|
|
||||||
|
NotificationBuilder builder = NotificationBuilder.getInstance(context);
|
||||||
|
builder.setSmallIcon(R.drawable.stat_notify_email_generic);
|
||||||
|
builder.setWhen(System.currentTimeMillis());
|
||||||
|
builder.setTicker(messageNotice);
|
||||||
|
|
||||||
final int unreadCount = previousUnreadMessageCount + newMessageCount.get();
|
final int unreadCount = previousUnreadMessageCount + newMessageCount.get();
|
||||||
if (account.isNotificationShowsUnreadCount()) {
|
if (account.isNotificationShowsUnreadCount()) {
|
||||||
notif.number = unreadCount;
|
builder.setNumber(unreadCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
Intent i = FolderList.actionHandleNotification(context, account, message.getFolder().getName());
|
String accountDescr = (account.getDescription() != null) ?
|
||||||
|
account.getDescription() : account.getEmail();
|
||||||
|
String accountNotice = context.getString(R.string.notification_new_one_account_fmt,
|
||||||
|
unreadCount, accountDescr);
|
||||||
|
builder.setContentTitle(accountNotice);
|
||||||
|
builder.setContentText(messageNotice);
|
||||||
|
|
||||||
|
Intent i = FolderList.actionHandleNotification(context, account,
|
||||||
|
message.getFolder().getName());
|
||||||
PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
|
PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
|
||||||
|
builder.setContentIntent(pi);
|
||||||
|
|
||||||
String accountDescr = (account.getDescription() != null) ? account.getDescription() : account.getEmail();
|
// Only ring or vibrate if we have not done so already on this account and fetch
|
||||||
String accountNotice = context.getString(R.string.notification_new_one_account_fmt, unreadCount, accountDescr);
|
|
||||||
notif.setLatestEventInfo(context, accountNotice, messageNotice, pi);
|
|
||||||
|
|
||||||
// Only ring or vibrate if we have not done so already on this
|
|
||||||
// account and fetch
|
|
||||||
boolean ringAndVibrate = false;
|
boolean ringAndVibrate = false;
|
||||||
if (!account.isRingNotified()) {
|
if (!account.isRingNotified()) {
|
||||||
account.setRingNotified(true);
|
account.setRingNotified(true);
|
||||||
@ -4151,38 +4218,36 @@ public class MessagingController implements Runnable {
|
|||||||
NotificationSetting n = account.getNotificationSetting();
|
NotificationSetting n = account.getNotificationSetting();
|
||||||
|
|
||||||
configureNotification(
|
configureNotification(
|
||||||
notif,
|
builder,
|
||||||
(n.shouldRing()) ? n.getRingtone() : null,
|
(n.shouldRing()) ? n.getRingtone() : null,
|
||||||
(n.shouldVibrate()) ? n.getVibration() : null,
|
(n.shouldVibrate()) ? n.getVibration() : null,
|
||||||
(n.isLed()) ? Integer.valueOf(n.getLedColor()) : null,
|
(n.isLed()) ? Integer.valueOf(n.getLedColor()) : null,
|
||||||
K9.NOTIFICATION_LED_BLINK_SLOW,
|
K9.NOTIFICATION_LED_BLINK_SLOW,
|
||||||
ringAndVibrate);
|
ringAndVibrate);
|
||||||
|
|
||||||
notifMgr.notify(account.getAccountNumber(), notif);
|
notifMgr.notify(account.getAccountNumber(), builder.getNotification());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param notification
|
* Configure the notification sound and LED
|
||||||
* Object to configure. Never <code>null</code>.
|
*
|
||||||
|
* @param builder
|
||||||
|
* {@link NotificationBuilder} instance used to configure the notification.
|
||||||
|
* Never {@code null}.
|
||||||
* @param ringtone
|
* @param ringtone
|
||||||
* String name of ringtone. <code>null</code> if no ringtone should be played
|
* String name of ringtone. {@code null}, if no ringtone should be played.
|
||||||
* @param vibrationPattern
|
* @param vibrationPattern
|
||||||
* <code>long[]</code> vibration pattern. <code>null</code> if no vibration should be played
|
* {@code long[]} vibration pattern. {@code null}, if no vibration should be played.
|
||||||
* @param ledColor
|
* @param ledColor
|
||||||
* <code>Integer</code> Color to flash LED. <code>null</code> if no LED flash should happen
|
* Color to flash LED. {@code null}, if no LED flash should happen.
|
||||||
* @param ledSpeed
|
* @param ledSpeed
|
||||||
* <code>int</code> should LEDs flash K9.NOTIFICATION_LED_BLINK_SLOW or K9.NOTIFICATION_LED_BLINK_FAST
|
* Either {@link K9#NOTIFICATION_LED_BLINK_SLOW} or
|
||||||
|
* {@link K9#NOTIFICATION_LED_BLINK_FAST}.
|
||||||
* @param ringAndVibrate
|
* @param ringAndVibrate
|
||||||
* <code>true</code> if ringtone/vibration are allowed,
|
* {@code true}, if ringtone/vibration are allowed. {@code false}, otherwise.
|
||||||
* <code>false</code> otherwise.
|
|
||||||
*/
|
*/
|
||||||
private void configureNotification(final Notification notification,
|
private void configureNotification(NotificationBuilder builder, String ringtone,
|
||||||
final String ringtone,
|
long[] vibrationPattern, Integer ledColor, int ledSpeed, boolean ringAndVibrate) {
|
||||||
final long[] vibrationPattern,
|
|
||||||
final Integer ledColor,
|
|
||||||
final int ledSpeed,
|
|
||||||
|
|
||||||
final boolean ringAndVibrate) {
|
|
||||||
|
|
||||||
// if it's quiet time, then we shouldn't be ringing, buzzing or flashing
|
// if it's quiet time, then we shouldn't be ringing, buzzing or flashing
|
||||||
if (K9.isQuietTime()) {
|
if (K9.isQuietTime()) {
|
||||||
@ -4190,25 +4255,27 @@ public class MessagingController implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ringAndVibrate) {
|
if (ringAndVibrate) {
|
||||||
if (ringtone != null) {
|
if (ringtone != null && !TextUtils.isEmpty(ringtone)) {
|
||||||
notification.sound = TextUtils.isEmpty(ringtone) ? null : Uri.parse(ringtone);
|
builder.setSound(Uri.parse(ringtone));
|
||||||
notification.audioStreamType = AudioManager.STREAM_NOTIFICATION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vibrationPattern != null) {
|
if (vibrationPattern != null) {
|
||||||
notification.vibrate = vibrationPattern;
|
builder.setVibrate(vibrationPattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ledColor != null) {
|
if (ledColor != null) {
|
||||||
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
|
int ledOnMS;
|
||||||
notification.ledARGB = ledColor;
|
int ledOffMS;
|
||||||
if (ledSpeed == K9.NOTIFICATION_LED_BLINK_SLOW) {
|
if (ledSpeed == K9.NOTIFICATION_LED_BLINK_SLOW) {
|
||||||
notification.ledOnMS = K9.NOTIFICATION_LED_ON_TIME;
|
ledOnMS = K9.NOTIFICATION_LED_ON_TIME;
|
||||||
notification.ledOffMS = K9.NOTIFICATION_LED_OFF_TIME;
|
ledOffMS = K9.NOTIFICATION_LED_OFF_TIME;
|
||||||
} else if (ledSpeed == K9.NOTIFICATION_LED_BLINK_FAST) {
|
} else {
|
||||||
notification.ledOnMS = K9.NOTIFICATION_LED_FAST_ON_TIME;
|
ledOnMS = K9.NOTIFICATION_LED_FAST_ON_TIME;
|
||||||
notification.ledOffMS = K9.NOTIFICATION_LED_FAST_OFF_TIME;
|
ledOffMS = K9.NOTIFICATION_LED_FAST_OFF_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.setLights(ledColor, ledOnMS, ledOffMS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
169
src/com/fsck/k9/helper/NotificationBuilder.java
Normal file
169
src/com/fsck/k9/helper/NotificationBuilder.java
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Vibrator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to create system notifications
|
||||||
|
*
|
||||||
|
* @see NotificationBuilderApi1
|
||||||
|
* @see NotificationBuilderApi11
|
||||||
|
*/
|
||||||
|
public abstract class NotificationBuilder {
|
||||||
|
/**
|
||||||
|
* Instance of the API-specific class that is used to create system notifications
|
||||||
|
*/
|
||||||
|
private static NotificationBuilder sInstance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get API-specific instance of the {@code NotificationBuilder} class
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* A {@link Context} instance.
|
||||||
|
*
|
||||||
|
* @return Appropriate {@link NotificationBuilder} instance for this device.
|
||||||
|
*/
|
||||||
|
public static NotificationBuilder getInstance(Context context) {
|
||||||
|
Context appContext = context.getApplicationContext();
|
||||||
|
|
||||||
|
if (sInstance == null) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||||
|
sInstance = new NotificationBuilderApi1(appContext);
|
||||||
|
} else {
|
||||||
|
sInstance = new NotificationBuilderApi11(appContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Context mContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* A {@link Context} instance.
|
||||||
|
*/
|
||||||
|
protected NotificationBuilder(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the small icon to use in the notification layouts.
|
||||||
|
*
|
||||||
|
* @param icon
|
||||||
|
* A resource ID in the application's package of the drawble to use.
|
||||||
|
*/
|
||||||
|
public abstract void setSmallIcon(int icon);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the time that the event occurred.
|
||||||
|
*
|
||||||
|
* @param when
|
||||||
|
* Timestamp of when the event occurred.
|
||||||
|
*/
|
||||||
|
public abstract void setWhen(long when);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the text that is displayed in the status bar when the notification first arrives.
|
||||||
|
*
|
||||||
|
* @param tickerText
|
||||||
|
* The text to display.
|
||||||
|
*/
|
||||||
|
public abstract void setTicker(CharSequence tickerText);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the title (first row) of the notification, in a standard notification.
|
||||||
|
*
|
||||||
|
* @param title
|
||||||
|
* The text to display as notification title.
|
||||||
|
*/
|
||||||
|
public abstract void setContentTitle(CharSequence title);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the text (second row) of the notification, in a standard notification.
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
* The text to display.
|
||||||
|
*/
|
||||||
|
public abstract void setContentText(CharSequence text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supply a PendingIntent to send when the notification is clicked.
|
||||||
|
*
|
||||||
|
* @param intent
|
||||||
|
* The intent that will be sent when the notification was clicked.
|
||||||
|
*/
|
||||||
|
public abstract void setContentIntent(PendingIntent intent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the large number at the right-hand side of the notification.
|
||||||
|
*
|
||||||
|
* @param number
|
||||||
|
* The number to display in the notification.
|
||||||
|
*/
|
||||||
|
public abstract void setNumber(int number);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether this is an ongoing notification.
|
||||||
|
*
|
||||||
|
* @param ongoing
|
||||||
|
* {@code true}, if it this is an ongoing notification. {@code false}, otherwise.
|
||||||
|
*/
|
||||||
|
public abstract void setOngoing(boolean ongoing);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setting this flag will make it so the notification is automatically canceled when the user
|
||||||
|
* clicks it in the panel.
|
||||||
|
*
|
||||||
|
* @param autoCancel
|
||||||
|
* {@code true}, if the notification should be automatically cancelled when the user
|
||||||
|
* clicks on it. {@code false}, otherwise.
|
||||||
|
*/
|
||||||
|
public abstract void setAutoCancel(boolean autoCancel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sound to play.
|
||||||
|
*
|
||||||
|
* It will play on the notification stream.
|
||||||
|
*
|
||||||
|
* @param sound
|
||||||
|
* The URI of the sound to play.
|
||||||
|
*/
|
||||||
|
public abstract void setSound(Uri sound);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the vibration pattern to use.
|
||||||
|
*
|
||||||
|
* @param pattern
|
||||||
|
* An array of longs of times for which to turn the vibrator on or off.
|
||||||
|
*
|
||||||
|
* @see Vibrator#vibrate(long[], int)
|
||||||
|
*/
|
||||||
|
public abstract void setVibrate(long[] pattern);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color that you would like the LED on the device to blink, as well as the rate.
|
||||||
|
*
|
||||||
|
* @param argb
|
||||||
|
* The color the LED should blink.
|
||||||
|
* @param onMs
|
||||||
|
* The number of milliseconds the LED should be on.
|
||||||
|
* @param offMs
|
||||||
|
* The number of milliseconds the LED should be off.
|
||||||
|
*/
|
||||||
|
public abstract void setLights(int argb, int onMs, int offMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combine all of the options that have been set and return a new {@link Notification} object.
|
||||||
|
*
|
||||||
|
* @return A new {@code Notification} object configured by this {@link NotificationBuilder}.
|
||||||
|
*/
|
||||||
|
public abstract Notification getNotification();
|
||||||
|
}
|
130
src/com/fsck/k9/helper/NotificationBuilderApi1.java
Normal file
130
src/com/fsck/k9/helper/NotificationBuilderApi1.java
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create notifications using the now deprecated {@link Notification} constructor.
|
||||||
|
*/
|
||||||
|
public class NotificationBuilderApi1 extends NotificationBuilder {
|
||||||
|
private int mSmallIcon;
|
||||||
|
private long mWhen;
|
||||||
|
private CharSequence mTickerText;
|
||||||
|
private CharSequence mContentText;
|
||||||
|
private CharSequence mContentTitle;
|
||||||
|
private PendingIntent mContentIntent;
|
||||||
|
private int mNumber;
|
||||||
|
private boolean mOngoing;
|
||||||
|
private boolean mAutoCancel;
|
||||||
|
private Uri mSoundUri;
|
||||||
|
private long[] mVibrationPattern;
|
||||||
|
private int mLedColor;
|
||||||
|
private int mLedOnMS;
|
||||||
|
private int mLedOffMS;
|
||||||
|
private boolean mBlinkLed;
|
||||||
|
|
||||||
|
|
||||||
|
protected NotificationBuilderApi1(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSmallIcon(int icon) {
|
||||||
|
mSmallIcon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWhen(long when) {
|
||||||
|
mWhen = when;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTicker(CharSequence tickerText) {
|
||||||
|
mTickerText = tickerText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentTitle(CharSequence title) {
|
||||||
|
mContentTitle = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentText(CharSequence text) {
|
||||||
|
mContentText = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentIntent(PendingIntent intent) {
|
||||||
|
mContentIntent = intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNumber(int number) {
|
||||||
|
mNumber = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOngoing(boolean ongoing) {
|
||||||
|
mOngoing = ongoing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAutoCancel(boolean autoCancel) {
|
||||||
|
mAutoCancel = autoCancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSound(Uri sound) {
|
||||||
|
mSoundUri = sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVibrate(long[] pattern) {
|
||||||
|
mVibrationPattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLights(int argb, int onMs, int offMs) {
|
||||||
|
mBlinkLed = true;
|
||||||
|
mLedColor = argb;
|
||||||
|
mLedOnMS = onMs;
|
||||||
|
mLedOffMS = offMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public Notification getNotification() {
|
||||||
|
Notification notification = new Notification(mSmallIcon, mTickerText, mWhen);
|
||||||
|
notification.number = mNumber;
|
||||||
|
notification.setLatestEventInfo(mContext, mContentTitle, mContentText, mContentIntent);
|
||||||
|
|
||||||
|
if (mSoundUri != null) {
|
||||||
|
notification.sound = mSoundUri;
|
||||||
|
notification.audioStreamType = AudioManager.STREAM_NOTIFICATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mVibrationPattern != null) {
|
||||||
|
notification.vibrate = mVibrationPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBlinkLed) {
|
||||||
|
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
|
||||||
|
notification.ledARGB = mLedColor;
|
||||||
|
notification.ledOnMS = mLedOnMS;
|
||||||
|
notification.ledOffMS = mLedOffMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mAutoCancel) {
|
||||||
|
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mOngoing) {
|
||||||
|
notification.flags |= Notification.FLAG_ONGOING_EVENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
}
|
86
src/com/fsck/k9/helper/NotificationBuilderApi11.java
Normal file
86
src/com/fsck/k9/helper/NotificationBuilderApi11.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create notifications using the new {@link android.app.Notification.Builder} class.
|
||||||
|
*/
|
||||||
|
public class NotificationBuilderApi11 extends NotificationBuilder {
|
||||||
|
private Notification.Builder mBuilder;
|
||||||
|
|
||||||
|
|
||||||
|
protected NotificationBuilderApi11(Context context) {
|
||||||
|
super(context);
|
||||||
|
mBuilder = new Notification.Builder(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSmallIcon(int icon) {
|
||||||
|
mBuilder.setSmallIcon(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWhen(long when) {
|
||||||
|
mBuilder.setWhen(when);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTicker(CharSequence tickerText) {
|
||||||
|
mBuilder.setTicker(tickerText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentTitle(CharSequence title) {
|
||||||
|
mBuilder.setContentTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentText(CharSequence text) {
|
||||||
|
mBuilder.setContentText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentIntent(PendingIntent intent) {
|
||||||
|
mBuilder.setContentIntent(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNumber(int number) {
|
||||||
|
mBuilder.setNumber(number);
|
||||||
|
mBuilder.setContentInfo("" + number);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOngoing(boolean ongoing) {
|
||||||
|
mBuilder.setOngoing(ongoing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAutoCancel(boolean autoCancel) {
|
||||||
|
mBuilder.setAutoCancel(autoCancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSound(Uri sound) {
|
||||||
|
mBuilder.setSound(sound, AudioManager.STREAM_NOTIFICATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVibrate(long[] pattern) {
|
||||||
|
mBuilder.setVibrate(pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLights(int argb, int onMs, int offMs) {
|
||||||
|
mBuilder.setLights(argb, onMs, offMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Notification getNotification() {
|
||||||
|
return mBuilder.getNotification();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user