1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-01-07 11:48:07 -05:00

#619 "Add android wear support"

* debugged stacked notifications (PendingIntents would reference wrong messages due to wrong handling of the PendingIntent mechanism)
* fixed dismissing notifications
This commit is contained in:
Marcus Wolschon 2015-07-14 18:40:05 +02:00
parent 0065004067
commit 28889f6430
3 changed files with 80 additions and 3 deletions

View File

@ -10,7 +10,10 @@ import android.app.Dialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.support.annotation.NonNull;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
@ -54,11 +57,17 @@ public class NotificationDeleteConfirmation extends Activity {
i.putExtra(EXTRA_ACCOUNT, account.getUuid());
i.putExtra(EXTRA_MESSAGE_LIST, refs);
i.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
// this is needed because Android considers 2 PendingIntents that only differ in Extras, the same
// and will return the already created PendingIntent instead.
// This MUST NOT lead to us returning a PendingIntent that deletes any other messages but the
// ones we have as parameters right now!!!
i.setData(Uri.parse("dummy://" + account.getUuid() + "/" + notificationID + "/notifydelete/" + refs.hashCode()));
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
// we can not use FLAG_UPDATE_CURRENT here because with Android Wear we may have
// PendingIntents for all new messages and for each individual new message at the same time.
return PendingIntent.getActivity(context, account.getAccountNumber(), i, PendingIntent.FLAG_ONE_SHOT);
return PendingIntent.getActivity(context, account.getAccountNumber(), i, 0);
}
@Override

View File

@ -4982,6 +4982,11 @@ public class MessagingController implements Runnable {
// no sound, no vibrate, no LED because these are for the summary notification only
// and depend on quiet time and user settings
// discarding the notification means this one message is no longer bening notified for
ArrayList<MessageReference> subAllRefs = new ArrayList<MessageReference>();
subAllRefs.add(message.makeMessageReference());
subBuilder.setDeleteIntent(NotificationActionService.getAcknowledgeIntent(context, account, realnID, subAllRefs));
// this must be done before the summary notification
notifMgr.notify(realnID, subBuilder.build());
data.addStackedChildNotification(m, realnID);
@ -5068,7 +5073,7 @@ public class MessagingController implements Runnable {
builder.setContentIntent(stack.getPendingIntent(
account.getAccountNumber(),
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT));
builder.setDeleteIntent(NotificationActionService.getAcknowledgeIntent(context, account, account.getAccountNumber()));
builder.setDeleteIntent(NotificationActionService.getAcknowledgeIntent(context, account, account.getAccountNumber(), allRefs));
// Only ring or vibrate if we have not done so already on this account and fetch
boolean ringAndVibrate = false;

View File

@ -20,6 +20,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
/**
@ -35,7 +36,13 @@ public class NotificationActionService extends CoreService {
private final static String ACKNOWLEDGE_ACTION = "com.fsck.k9.service.NotificationActionService.ACKNOWLEDGE_ACTION";
private final static String EXTRA_ACCOUNT = "account";
/**
* Single message reference.
*/
private final static String EXTRA_MESSAGE = "message";
/**
* Serialized message list of references.
*/
private final static String EXTRA_MESSAGE_LIST = "messages";
/**
* ID of the notification that triggered an intent.
@ -60,6 +67,12 @@ public class NotificationActionService extends CoreService {
i.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
i.setAction(REPLY_ACTION);
// this is needed because Android considers 2 PendingIntents that only differ in Extras, the same
// and will return the already created PendingIntent instead.
// This MUST NOT lead to us returning a PendingIntent that deletes any other messages but the
// ones we have as parameters right now!!!
i.setData(Uri.parse("dummy://" + account.getUuid() + "/" + notificationID + "/reply/" + ref.getUid()));
return PendingIntent.getService(context, account.getAccountNumber(), i, PendingIntent.FLAG_UPDATE_CURRENT);
}
@ -79,6 +92,12 @@ public class NotificationActionService extends CoreService {
i.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
i.setAction(READ_ALL_ACTION);
// this is needed because Android considers 2 PendingIntents that only differ in Extras, the same
// and will return the already created PendingIntent instead.
// This MUST NOT lead to us returning a PendingIntent that deletes any other messages but the
// ones we have as parameters right now!!!
i.setData(Uri.parse("dummy://" + account.getUuid() + "/" + notificationID + "/read/" + refs.hashCode()));
return PendingIntent.getService(context, account.getAccountNumber(), i, PendingIntent.FLAG_UPDATE_CURRENT);
}
@ -90,12 +109,36 @@ public class NotificationActionService extends CoreService {
* @return the requested intent. To be used in a Notification.
* @see #EXTRA_NOTIFICATION_ID
*/
public static PendingIntent getAcknowledgeIntent(Context context, final Account account, final int notificationID) {
/* public static PendingIntent getAcknowledgeIntent(Context context, final Account account, final int notificationID) {
Intent i = new Intent(context, NotificationActionService.class);
i.putExtra(EXTRA_ACCOUNT, account.getUuid());
i.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
i.setAction(ACKNOWLEDGE_ACTION);
return PendingIntent.getService(context, account.getAccountNumber(), i, PendingIntent.FLAG_UPDATE_CURRENT);
}*/
/**
*
* @param context context to use for creating the {@link Intent}
* @param account the account for the intent to act on
* @param notificationID ID of the notification, this intent is for.
* @param refs these messages are acknowledged and shoud not be notified for anymore.
* @return the requested intent. To be used in a Notification.
* @see #EXTRA_NOTIFICATION_ID
*/
public static PendingIntent getAcknowledgeIntent(Context context, final Account account, final int notificationID, final Serializable refs) {
Intent i = new Intent(context, NotificationActionService.class);
i.putExtra(EXTRA_ACCOUNT, account.getUuid());
i.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
i.putExtra(EXTRA_MESSAGE_LIST, refs);
i.setAction(ACKNOWLEDGE_ACTION);
// this is needed because Android considers 2 PendingIntents that only differ in Extras, the same
// and will return the already created PendingIntent instead.
// This MUST NOT lead to us returning a PendingIntent that deletes any other messages but the
// ones we have as parameters right now!!!
i.setData(Uri.parse("dummy://" + account.getUuid() + "/" + notificationID + "/ack/" + refs.hashCode()));
return PendingIntent.getService(context, account.getAccountNumber(), i, PendingIntent.FLAG_UPDATE_CURRENT);
}
@ -115,6 +158,12 @@ public class NotificationActionService extends CoreService {
i.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
i.setAction(DELETE_ALL_ACTION);
// this is needed because Android considers 2 PendingIntents that only differ in Extras, the same
// and will return the already created PendingIntent instead.
// This MUST NOT lead to us returning a PendingIntent that deletes any other messages but the
// ones we have as parameters right now!!!
i.setData(Uri.parse("dummy://" + account.getUuid() + "/" + notificationID + "/delete/" + refs.hashCode()));
return i;
}
@ -149,6 +198,12 @@ public class NotificationActionService extends CoreService {
i.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
i.setAction(ARCHIVE_ALL_ACTION);
// this is needed because Android considers 2 PendingIntents that only differ in Extras, the same
// and will return the already created PendingIntent instead.
// This MUST NOT lead to us returning a PendingIntent that deletes any other messages but the
// ones we have as parameters right now!!!
i.setData(Uri.parse("dummy://" + account.getUuid() + "/" + notificationID + "/archive/" + refs.hashCode()));
return PendingIntent.getService(context, account.getAccountNumber(), i, PendingIntent.FLAG_UPDATE_CURRENT);
}
@ -184,6 +239,12 @@ public class NotificationActionService extends CoreService {
i.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
i.setAction(SPAM_ALL_ACTION);
// this is needed because Android considers 2 PendingIntents that only differ in Extras, the same
// and will return the already created PendingIntent instead.
// This MUST NOT lead to us returning a PendingIntent that deletes any other messages but the
// ones we have as parameters right now!!!
i.setData(Uri.parse("dummy://" + account.getUuid() + "/" + notificationID + "/spam/" + refs.hashCode()));
return PendingIntent.getService(context, account.getAccountNumber(), i, PendingIntent.FLAG_UPDATE_CURRENT);
}
@ -305,6 +366,8 @@ public class NotificationActionService extends CoreService {
// nothing to do here, we just want to cancel the notification so the list
// of unseen messages is reset
Log.i(K9.LOG_TAG, "notification acknowledged");
refs = intent.getParcelableArrayListExtra(EXTRA_MESSAGE_LIST);
}
// if this was a stacked notification on Android Wear, update the summary