use N style stacked notifications
This commit is contained in:
		
							parent
							
								
									a4d342683e
								
							
						
					
					
						commit
						542626758d
					
				| @ -27,6 +27,7 @@ import java.util.Calendar; | |||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.LinkedHashMap; | import java.util.LinkedHashMap; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
| import java.util.regex.Matcher; | import java.util.regex.Matcher; | ||||||
| import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||||
| 
 | 
 | ||||||
| @ -43,6 +44,7 @@ import eu.siacs.conversations.utils.UIHelper; | |||||||
| 
 | 
 | ||||||
| public class NotificationService { | public class NotificationService { | ||||||
| 
 | 
 | ||||||
|  | 	private static final String CONVERSATIONS_GROUP = "eu.siacs.conversations"; | ||||||
| 	private final XmppConnectionService mXmppConnectionService; | 	private final XmppConnectionService mXmppConnectionService; | ||||||
| 
 | 
 | ||||||
| 	private final LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<>(); | 	private final LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<>(); | ||||||
| @ -181,10 +183,6 @@ public class NotificationService { | |||||||
| 				.getSystemService(Context.NOTIFICATION_SERVICE); | 				.getSystemService(Context.NOTIFICATION_SERVICE); | ||||||
| 		final SharedPreferences preferences = mXmppConnectionService.getPreferences(); | 		final SharedPreferences preferences = mXmppConnectionService.getPreferences(); | ||||||
| 
 | 
 | ||||||
| 		final String ringtone = preferences.getString("notification_ringtone", null); |  | ||||||
| 		final boolean vibrate = preferences.getBoolean("vibrate_on_notification", true); |  | ||||||
| 		final boolean led = preferences.getBoolean("led", true); |  | ||||||
| 
 |  | ||||||
| 		if (notifications.size() == 0) { | 		if (notifications.size() == 0) { | ||||||
| 			notificationManager.cancel(NOTIFICATION_ID); | 			notificationManager.cancel(NOTIFICATION_ID); | ||||||
| 		} else { | 		} else { | ||||||
| @ -193,10 +191,28 @@ public class NotificationService { | |||||||
| 			} | 			} | ||||||
| 			final Builder mBuilder; | 			final Builder mBuilder; | ||||||
| 			if (notifications.size() == 1) { | 			if (notifications.size() == 1) { | ||||||
| 				mBuilder = buildSingleConversations(notify); | 				mBuilder = buildSingleConversations(notifications.values().iterator().next()); | ||||||
|  | 				modifyForSoundVibrationAndLight(mBuilder, notify, preferences); | ||||||
|  | 				notificationManager.notify(NOTIFICATION_ID, mBuilder.build()); | ||||||
| 			} else { | 			} else { | ||||||
| 				mBuilder = buildMultipleConversation(); | 				mBuilder = buildMultipleConversation(); | ||||||
|  | 				modifyForSoundVibrationAndLight(mBuilder, notify, preferences); | ||||||
|  | 				notificationManager.notify(NOTIFICATION_ID, mBuilder.build()); | ||||||
|  | 				for(Map.Entry<String,ArrayList<Message>> entry : notifications.entrySet()) { | ||||||
|  | 					Builder singleBuilder = buildSingleConversations(entry.getValue()); | ||||||
|  | 					singleBuilder.setGroup(CONVERSATIONS_GROUP); | ||||||
|  | 					modifyForSoundVibrationAndLight(singleBuilder,notify,preferences); | ||||||
|  | 					notificationManager.notify(entry.getKey().hashCode() % 435301 ,singleBuilder.build()); | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	private void modifyForSoundVibrationAndLight(Builder mBuilder, boolean notify, SharedPreferences preferences) { | ||||||
|  | 		final String ringtone = preferences.getString("notification_ringtone", null); | ||||||
|  | 		final boolean vibrate = preferences.getBoolean("vibrate_on_notification", true); | ||||||
|  | 		final boolean led = preferences.getBoolean("led", true); | ||||||
| 		if (notify && !isQuietHours()) { | 		if (notify && !isQuietHours()) { | ||||||
| 			if (vibrate) { | 			if (vibrate) { | ||||||
| 				final int dat = 70; | 				final int dat = 70; | ||||||
| @ -212,14 +228,9 @@ public class NotificationService { | |||||||
| 		} | 		} | ||||||
| 		setNotificationColor(mBuilder); | 		setNotificationColor(mBuilder); | ||||||
| 		mBuilder.setDefaults(0); | 		mBuilder.setDefaults(0); | ||||||
| 			mBuilder.setSmallIcon(R.drawable.ic_notification); |  | ||||||
| 			mBuilder.setDeleteIntent(createDeleteIntent()); |  | ||||||
| 		if (led) { | 		if (led) { | ||||||
| 			mBuilder.setLights(0xff00FF00, 2000, 3000); | 			mBuilder.setLights(0xff00FF00, 2000, 3000); | ||||||
| 		} | 		} | ||||||
| 			final Notification notification = mBuilder.build(); |  | ||||||
| 			notificationManager.notify(NOTIFICATION_ID, notification); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private Builder buildMultipleConversation() { | 	private Builder buildMultipleConversation() { | ||||||
| @ -259,13 +270,15 @@ public class NotificationService { | |||||||
| 		if (conversation != null) { | 		if (conversation != null) { | ||||||
| 			mBuilder.setContentIntent(createContentIntent(conversation)); | 			mBuilder.setContentIntent(createContentIntent(conversation)); | ||||||
| 		} | 		} | ||||||
|  | 		mBuilder.setGroupSummary(true); | ||||||
|  | 		mBuilder.setGroup(CONVERSATIONS_GROUP); | ||||||
|  | 		mBuilder.setDeleteIntent(createDeleteIntent(null)); | ||||||
|  | 		mBuilder.setSmallIcon(R.drawable.ic_notification); | ||||||
| 		return mBuilder; | 		return mBuilder; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private Builder buildSingleConversations(final boolean notify) { | 	private Builder buildSingleConversations(final ArrayList<Message> messages) { | ||||||
| 		final Builder mBuilder = new NotificationCompat.Builder( | 		final Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService); | ||||||
| 				mXmppConnectionService); |  | ||||||
| 		final ArrayList<Message> messages = notifications.values().iterator().next(); |  | ||||||
| 		if (messages.size() >= 1) { | 		if (messages.size() >= 1) { | ||||||
| 			final Conversation conversation = messages.get(0).getConversation(); | 			final Conversation conversation = messages.get(0).getConversation(); | ||||||
| 			mBuilder.setLargeIcon(mXmppConnectionService.getAvatarService() | 			mBuilder.setLargeIcon(mXmppConnectionService.getAvatarService() | ||||||
| @ -277,11 +290,9 @@ public class NotificationService { | |||||||
| 			} else { | 			} else { | ||||||
| 				Message message; | 				Message message; | ||||||
| 				if ((message = getImage(messages)) != null) { | 				if ((message = getImage(messages)) != null) { | ||||||
| 					modifyForImage(mBuilder, message, messages, notify); | 					modifyForImage(mBuilder, message, messages); | ||||||
| 				} else if (conversation.getMode() == Conversation.MODE_MULTI) { |  | ||||||
| 					modifyForConference(mBuilder, conversation, messages, notify); |  | ||||||
| 				} else { | 				} else { | ||||||
| 					modifyForTextOnly(mBuilder, messages, notify); | 					modifyForTextOnly(mBuilder, messages); | ||||||
| 				} | 				} | ||||||
| 				if ((message = getFirstDownloadableMessage(messages)) != null) { | 				if ((message = getFirstDownloadableMessage(messages)) != null) { | ||||||
| 					mBuilder.addAction( | 					mBuilder.addAction( | ||||||
| @ -298,13 +309,16 @@ public class NotificationService { | |||||||
| 							createShowLocationIntent(message)); | 							createShowLocationIntent(message)); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 			mBuilder.setWhen(conversation.getLatestMessage().getTimeSent()); | ||||||
|  | 			mBuilder.setSmallIcon(R.drawable.ic_notification); | ||||||
|  | 			mBuilder.setDeleteIntent(createDeleteIntent(conversation)); | ||||||
| 			mBuilder.setContentIntent(createContentIntent(conversation)); | 			mBuilder.setContentIntent(createContentIntent(conversation)); | ||||||
| 		} | 		} | ||||||
| 		return mBuilder; | 		return mBuilder; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void modifyForImage(final Builder builder, final Message message, | 	private void modifyForImage(final Builder builder, final Message message, | ||||||
| 								final ArrayList<Message> messages, final boolean notify) { | 								final ArrayList<Message> messages) { | ||||||
| 		try { | 		try { | ||||||
| 			final Bitmap bitmap = mXmppConnectionService.getFileBackend() | 			final Bitmap bitmap = mXmppConnectionService.getFileBackend() | ||||||
| 					.getThumbnail(message, getPixel(288), false); | 					.getThumbnail(message, getPixel(288), false); | ||||||
| @ -327,36 +341,25 @@ public class NotificationService { | |||||||
| 			} | 			} | ||||||
| 			builder.setStyle(bigPictureStyle); | 			builder.setStyle(bigPictureStyle); | ||||||
| 		} catch (final FileNotFoundException e) { | 		} catch (final FileNotFoundException e) { | ||||||
| 			modifyForTextOnly(builder, messages, notify); | 			modifyForTextOnly(builder, messages); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void modifyForTextOnly(final Builder builder, | 	private void modifyForTextOnly(final Builder builder, final ArrayList<Message> messages) { | ||||||
| 								   final ArrayList<Message> messages, final boolean notify) { | 		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||||||
|  | 			NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle(mXmppConnectionService.getString(R.string.me)); | ||||||
|  | 			Conversation conversation = messages.get(0).getConversation(); | ||||||
|  | 			if (conversation.getMode() == Conversation.MODE_MULTI) { | ||||||
|  | 				messagingStyle.setConversationTitle(conversation.getName()); | ||||||
|  | 			} | ||||||
|  | 			for (Message message : messages) { | ||||||
|  | 				String sender = message.getStatus() == Message.STATUS_RECEIVED ? UIHelper.getMessageDisplayName(message) : null; | ||||||
|  | 				messagingStyle.addMessage(message.getBody().trim(), message.getTimeSent(), sender); | ||||||
|  | 			} | ||||||
|  | 			builder.setStyle(messagingStyle); | ||||||
|  | 		} else { | ||||||
| 			builder.setStyle(new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages))); | 			builder.setStyle(new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages))); | ||||||
| 			builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService, messages.get(0)).first); | 			builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService, messages.get(0)).first); | ||||||
| 		if (notify) { |  | ||||||
| 			builder.setTicker(UIHelper.getMessagePreview(mXmppConnectionService, messages.get(messages.size() - 1)).first); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	private void modifyForConference(Builder builder, Conversation conversation, List<Message> messages, boolean notify) { |  | ||||||
| 		final Message first = messages.get(0); |  | ||||||
| 		final Message last = messages.get(messages.size() - 1); |  | ||||||
| 		final NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); |  | ||||||
| 		style.setBigContentTitle(conversation.getName()); |  | ||||||
| 
 |  | ||||||
| 		for(Message message : messages) { |  | ||||||
| 			if (message.hasMeCommand()) { |  | ||||||
| 				style.addLine(UIHelper.getMessagePreview(mXmppConnectionService,message).first); |  | ||||||
| 			} else { |  | ||||||
| 				style.addLine(Html.fromHtml("<b>" + UIHelper.getMessageDisplayName(message) + "</b>: " + UIHelper.getMessagePreview(mXmppConnectionService, message).first)); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		builder.setContentText((first.hasMeCommand() ? "" :UIHelper.getMessageDisplayName(first)+ ": ") +UIHelper.getMessagePreview(mXmppConnectionService, first).first); |  | ||||||
| 		builder.setStyle(style); |  | ||||||
| 		if (notify) { |  | ||||||
| 			builder.setTicker((last.hasMeCommand() ? "" : UIHelper.getMessageDisplayName(last) + ": ") + UIHelper.getMessagePreview(mXmppConnectionService,last).first); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -417,18 +420,16 @@ public class NotificationService { | |||||||
| 	private PendingIntent createContentIntent(final String conversationUuid, final String downloadMessageUuid) { | 	private PendingIntent createContentIntent(final String conversationUuid, final String downloadMessageUuid) { | ||||||
| 		final Intent viewConversationIntent = new Intent(mXmppConnectionService,ConversationActivity.class); | 		final Intent viewConversationIntent = new Intent(mXmppConnectionService,ConversationActivity.class); | ||||||
| 		viewConversationIntent.setAction(ConversationActivity.ACTION_VIEW_CONVERSATION); | 		viewConversationIntent.setAction(ConversationActivity.ACTION_VIEW_CONVERSATION); | ||||||
| 		if (conversationUuid != null) { |  | ||||||
| 		viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, conversationUuid); | 		viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, conversationUuid); | ||||||
| 		} |  | ||||||
| 		if (downloadMessageUuid != null) { | 		if (downloadMessageUuid != null) { | ||||||
| 			viewConversationIntent.putExtra(ConversationActivity.EXTRA_DOWNLOAD_UUID, downloadMessageUuid); | 			viewConversationIntent.putExtra(ConversationActivity.EXTRA_DOWNLOAD_UUID, downloadMessageUuid); | ||||||
| 			return PendingIntent.getActivity(mXmppConnectionService, | 			return PendingIntent.getActivity(mXmppConnectionService, | ||||||
| 					57, | 					conversationUuid.hashCode() % 389782, | ||||||
| 					viewConversationIntent, | 					viewConversationIntent, | ||||||
| 					PendingIntent.FLAG_UPDATE_CURRENT); | 					PendingIntent.FLAG_UPDATE_CURRENT); | ||||||
| 		} else { | 		} else { | ||||||
| 			return PendingIntent.getActivity(mXmppConnectionService, | 			return PendingIntent.getActivity(mXmppConnectionService, | ||||||
| 					58, | 					conversationUuid.hashCode() % 936236, | ||||||
| 					viewConversationIntent, | 					viewConversationIntent, | ||||||
| 					PendingIntent.FLAG_UPDATE_CURRENT); | 					PendingIntent.FLAG_UPDATE_CURRENT); | ||||||
| 		} | 		} | ||||||
| @ -442,10 +443,13 @@ public class NotificationService { | |||||||
| 		return createContentIntent(conversation.getUuid(), null); | 		return createContentIntent(conversation.getUuid(), null); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private PendingIntent createDeleteIntent() { | 	private PendingIntent createDeleteIntent(Conversation conversation) { | ||||||
| 		final Intent intent = new Intent(mXmppConnectionService, | 		final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); | ||||||
| 				XmppConnectionService.class); |  | ||||||
| 		intent.setAction(XmppConnectionService.ACTION_CLEAR_NOTIFICATION); | 		intent.setAction(XmppConnectionService.ACTION_CLEAR_NOTIFICATION); | ||||||
|  | 		if (conversation != null) { | ||||||
|  | 			intent.putExtra("uuid", conversation.getUuid()); | ||||||
|  | 			return PendingIntent.getService(mXmppConnectionService, conversation.getUuid().hashCode() % 47528, intent, 0); | ||||||
|  | 		} | ||||||
| 		return PendingIntent.getService(mXmppConnectionService, 0, intent, 0); | 		return PendingIntent.getService(mXmppConnectionService, 0, intent, 0); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -536,6 +540,8 @@ public class NotificationService { | |||||||
| 		mBuilder.setContentIntent(createOpenConversationsIntent()); | 		mBuilder.setContentIntent(createOpenConversationsIntent()); | ||||||
| 		mBuilder.setWhen(0); | 		mBuilder.setWhen(0); | ||||||
| 		mBuilder.setPriority(Config.SHOW_CONNECTED_ACCOUNTS ? NotificationCompat.PRIORITY_DEFAULT : NotificationCompat.PRIORITY_MIN); | 		mBuilder.setPriority(Config.SHOW_CONNECTED_ACCOUNTS ? NotificationCompat.PRIORITY_DEFAULT : NotificationCompat.PRIORITY_MIN); | ||||||
|  | 		mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp); | ||||||
|  | 		if (Config.SHOW_DISABLE_FOREGROUND) { | ||||||
| 			final int cancelIcon; | 			final int cancelIcon; | ||||||
| 			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | 			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||||
| 				mBuilder.setCategory(Notification.CATEGORY_SERVICE); | 				mBuilder.setCategory(Notification.CATEGORY_SERVICE); | ||||||
| @ -543,8 +549,6 @@ public class NotificationService { | |||||||
| 			} else { | 			} else { | ||||||
| 				cancelIcon = R.drawable.ic_action_cancel; | 				cancelIcon = R.drawable.ic_action_cancel; | ||||||
| 			} | 			} | ||||||
| 		mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp); |  | ||||||
| 		if (Config.SHOW_DISABLE_FOREGROUND) { |  | ||||||
| 			mBuilder.addAction(cancelIcon, | 			mBuilder.addAction(cancelIcon, | ||||||
| 					mXmppConnectionService.getString(R.string.disable_foreground_service), | 					mXmppConnectionService.getString(R.string.disable_foreground_service), | ||||||
| 					createDisableForeground()); | 					createDisableForeground()); | ||||||
|  | |||||||
| @ -541,7 +541,12 @@ public class XmppConnectionService extends Service { | |||||||
| 					logoutAndSave(true); | 					logoutAndSave(true); | ||||||
| 					return START_NOT_STICKY; | 					return START_NOT_STICKY; | ||||||
| 				case ACTION_CLEAR_NOTIFICATION: | 				case ACTION_CLEAR_NOTIFICATION: | ||||||
|  | 					final Conversation c = findConversationByUuid(intent.getStringExtra("uuid")); | ||||||
|  | 					if (c != null) { | ||||||
|  | 						mNotificationService.clear(c); | ||||||
|  | 					} else { | ||||||
| 						mNotificationService.clear(); | 						mNotificationService.clear(); | ||||||
|  | 					} | ||||||
| 					break; | 					break; | ||||||
| 				case ACTION_DISABLE_FOREGROUND: | 				case ACTION_DISABLE_FOREGROUND: | ||||||
| 					getPreferences().edit().putBoolean("keep_foreground_service", false).commit(); | 					getPreferences().edit().putBoolean("keep_foreground_service", false).commit(); | ||||||
|  | |||||||
| @ -676,4 +676,5 @@ | |||||||
| 	<string name="type_console">Console</string> | 	<string name="type_console">Console</string> | ||||||
| 	<string name="payment_required">Payment required</string> | 	<string name="payment_required">Payment required</string> | ||||||
| 	<string name="missing_internet_permission">Missing internet permission</string> | 	<string name="missing_internet_permission">Missing internet permission</string> | ||||||
|  | 	<string name="me">Me</string> | ||||||
| </resources> | </resources> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch