package im.actor.sdk.core; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.media.AudioManager; import android.media.SoundPool; import android.support.v4.app.NotificationCompat; import android.support.v4.graphics.drawable.RoundedBitmapDrawable; import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; import android.text.SpannableStringBuilder; import android.text.style.StyleSpan; import org.jetbrains.annotations.NotNull; import java.util.List; import im.actor.core.AndroidMessenger; import im.actor.core.Messenger; import im.actor.core.providers.NotificationProvider; import im.actor.core.entity.Avatar; import im.actor.core.entity.Notification; import im.actor.core.entity.Peer; import im.actor.core.entity.PeerType; import im.actor.core.viewmodel.FileVMCallback; import im.actor.sdk.R; import im.actor.sdk.controllers.Intents; import im.actor.sdk.controllers.root.RootActivity; import im.actor.sdk.util.Screen; import im.actor.sdk.view.avatar.AvatarPlaceholderDrawable; import im.actor.runtime.files.FileSystemReference; import im.actor.sdk.ActorSDK; public class AndroidNotifications implements NotificationProvider { private static final int NOTIFICATION_ID = 1; private SoundPool soundPool; private int soundId; private Peer visiblePeer; private Context context; private Intent intent; public AndroidNotifications(Context context) { this.context = context; } private AndroidMessenger messenger() { return ActorSDK.sharedActor().getMessenger(); } @Override public void onMessageArriveInApp(Messenger messenger) { if (soundPool == null) { soundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); soundId = soundPool.load(context, R.raw.notification, 1); } soundPool.play(soundId, 1.0f, 1.0f, 0, 0, 1.0f); } @Override public void onNotification(Messenger messenger, List<Notification> topNotifications, int messagesCount, int conversationsCount) { final NotificationCompat.Builder builder = new NotificationCompat.Builder(context); builder.setAutoCancel(true); builder.setSmallIcon(R.drawable.ic_app_notify); builder.setPriority(NotificationCompat.PRIORITY_DEFAULT); builder.setCategory(NotificationCompat.CATEGORY_MESSAGE); int defaults = NotificationCompat.DEFAULT_LIGHTS; if (messenger.isNotificationVibrationEnabled()) { defaults |= NotificationCompat.DEFAULT_VIBRATE; } // if (silentUpdate) { // defaults = 0; // } builder.setDefaults(defaults); // Wearable // builder.extend(new NotificationCompat.WearableExtender() // .setBackground(((BitmapDrawable) AppContext.getContext().getResources().getDrawable(R.drawable.wear_bg)).getBitmap()) // .setHintHideIcon(true)); final Notification topNotification = topNotifications.get(topNotifications.size() - 1); // if (!silentUpdate) { // builder.setTicker(getNotificationTextFull(topNotification, messenger)); // } android.app.Notification result; if (messagesCount == 1) { // Single message notification final String sender = getNotificationSender(topNotification); // final CharSequence text = bypass.markdownToSpannable(messenger().getFormatter().formatNotificationText(topNotification), true).toString(); final CharSequence text = messenger.getFormatter().formatNotificationText(topNotification); visiblePeer = topNotification.getPeer(); Avatar avatar = null; int id = 0; String avatarTitle = ""; switch (visiblePeer.getPeerType()) { case PRIVATE: avatar = messenger().getUsers().get(visiblePeer.getPeerId()).getAvatar().get(); id = messenger().getUsers().get(visiblePeer.getPeerId()).getId(); avatarTitle = messenger().getUsers().get(visiblePeer.getPeerId()).getName().get(); break; case GROUP: avatar = messenger().getGroups().get(visiblePeer.getPeerId()).getAvatar().get(); id = messenger().getGroups().get(visiblePeer.getPeerId()).getId(); avatarTitle = messenger().getGroups().get(visiblePeer.getPeerId()).getName().get(); break; } Drawable avatarDrawable = new AvatarPlaceholderDrawable(avatarTitle, id, 18, context); result = buildSingleMessageNotification(avatarDrawable, builder, sender, text, topNotification); final NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(NOTIFICATION_ID, result); if (avatar != null && avatar.getSmallImage() != null && avatar.getSmallImage().getFileReference() != null) { messenger.bindFile(avatar.getSmallImage().getFileReference(), true, new FileVMCallback() { @Override public void onNotDownloaded() { } @Override public void onDownloading(float progress) { } @Override public void onDownloaded(FileSystemReference reference) { RoundedBitmapDrawable d = getRoundedBitmapDrawable(reference); android.app.Notification result = buildSingleMessageNotification(d, builder, sender, text, topNotification); //NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(NOTIFICATION_ID, result); } }); } else { manager.notify(NOTIFICATION_ID, result); } } else if (conversationsCount == 1) { // Single conversation notification String sender = getNotificationSender(topNotification); builder.setContentTitle(sender); builder.setContentText(messagesCount + context.getString(R.string.notifications_single_conversation_аfter_messages_count)); visiblePeer = topNotification.getPeer(); final NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); for (Notification n : topNotifications) { if (topNotification.getPeer().getPeerType() == PeerType.GROUP) { inboxStyle.addLine(getNotificationTextFull(n, messenger)); } else { inboxStyle.addLine(messenger.getFormatter().formatNotificationText(n)); } } inboxStyle.setSummaryText(messagesCount + context.getString(R.string.notifications_single_conversation_аfter_messages_count)); Avatar avatar = null; int id = 0; String avatarTitle = ""; switch (visiblePeer.getPeerType()) { case PRIVATE: avatar = messenger().getUsers().get(visiblePeer.getPeerId()).getAvatar().get(); id = messenger().getUsers().get(visiblePeer.getPeerId()).getId(); avatarTitle = messenger().getUsers().get(visiblePeer.getPeerId()).getName().get(); break; case GROUP: avatar = messenger().getGroups().get(visiblePeer.getPeerId()).getAvatar().get(); id = messenger().getGroups().get(visiblePeer.getPeerId()).getId(); avatarTitle = messenger().getGroups().get(visiblePeer.getPeerId()).getName().get(); break; } Drawable avatarDrawable = new AvatarPlaceholderDrawable(avatarTitle, id, 18, context); result = buildSingleConversationNotification(builder, inboxStyle, avatarDrawable, topNotification); final NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(NOTIFICATION_ID, result); if (avatar != null && avatar.getSmallImage() != null && avatar.getSmallImage().getFileReference() != null) { messenger.bindFile(avatar.getSmallImage().getFileReference(), true, new FileVMCallback() { @Override public void onNotDownloaded() { } @Override public void onDownloading(float progress) { } @Override public void onDownloaded(FileSystemReference reference) { RoundedBitmapDrawable d = getRoundedBitmapDrawable(reference); android.app.Notification result = buildSingleConversationNotification(builder, inboxStyle, d, topNotification); manager.notify(NOTIFICATION_ID, result); } }); } else { manager.notify(NOTIFICATION_ID, result); } } else { // Multiple conversations notification builder.setContentTitle(ActorSDK.sharedActor().getAppName()); builder.setContentText(messagesCount + context.getString(R.string.notification_multiple_canversations_after_msg_count) + conversationsCount + context.getString(R.string.notifications_multiple_canversations_after_coversations_count)); visiblePeer = null; intent = new Intent(context, RootActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); builder.setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); for (Notification n : topNotifications) { inboxStyle.addLine(getNotificationTextFull(n, messenger)); } inboxStyle.setSummaryText(messagesCount + context.getString(R.string.notification_multiple_canversations_after_msg_count) + conversationsCount + context.getString(R.string.notifications_multiple_canversations_after_coversations_count)); result = builder .setStyle(inboxStyle) .build(); addCustomLedAndSound(topNotification, result); NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(NOTIFICATION_ID, result); } } public void addCustomLedAndSound(Notification topNotification, android.app.Notification result) { if (messenger().isNotificationSoundEnabled()) { result.defaults &= ~NotificationCompat.DEFAULT_SOUND; result.sound = ActorSDK.sharedActor().getDelegate().getNotificationSoundForPeer(topNotification.getPeer()); } result.ledARGB = ActorSDK.sharedActor().getDelegate().getNotificationColorForPeer(topNotification.getPeer()); if (result.ledARGB != 0) { result.ledOnMS = 100; result.ledOffMS = 100; result.defaults &= ~NotificationCompat.DEFAULT_LIGHTS; result.flags |= NotificationCompat.FLAG_SHOW_LIGHTS; } } @Override public void onUpdateNotification(Messenger messenger, List<Notification> topNotifications, int messagesCount, int conversationsCount) { // TODO: Implement } @Override public void hideAllNotifications() { NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); manager.cancel(NOTIFICATION_ID); } @NotNull private RoundedBitmapDrawable getRoundedBitmapDrawable(FileSystemReference reference) { Bitmap b = BitmapFactory.decodeFile(reference.getDescriptor()); RoundedBitmapDrawable d = RoundedBitmapDrawableFactory.create(context.getResources(), Bitmap.createScaledBitmap(b, Screen.dp(55), Screen.dp(55), false)); d.setCornerRadius(d.getIntrinsicHeight() / 2); d.setAntiAlias(true); return d; } private android.app.Notification buildSingleConversationNotification(NotificationCompat.Builder builder, NotificationCompat.InboxStyle inboxStyle, Drawable avatarDrawable, Notification topNotification) { android.app.Notification notification = builder .setLargeIcon(drawableToBitmap(avatarDrawable)) .setContentIntent(PendingIntent.getActivity(context, 0, Intents.openDialog(topNotification.getPeer(), false, context), PendingIntent.FLAG_UPDATE_CURRENT)) .setStyle(inboxStyle) .build(); addCustomLedAndSound(topNotification, notification); return notification; } private android.app.Notification buildSingleMessageNotification(Drawable d, NotificationCompat.Builder builder, String sender, CharSequence text, Notification topNotification) { android.app.Notification notification = builder .setContentTitle(sender) .setContentText(text) .setLargeIcon(drawableToBitmap(d)) .setContentIntent(PendingIntent.getActivity(context, 0, Intents.openDialog(topNotification.getPeer(), false, context), PendingIntent.FLAG_CANCEL_CURRENT)) .setStyle(new NotificationCompat.BigTextStyle().bigText(text)) .build(); addCustomLedAndSound(topNotification, notification); return notification; } public static Bitmap drawableToBitmap(Drawable drawable) { int height = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(height > 0 ? height : Screen.dp(55), height > 0 ? height : Screen.dp(55), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } private CharSequence getNotificationTextFull(Notification notification, Messenger messenger) { SpannableStringBuilder res = new SpannableStringBuilder(); if (!messenger.getFormatter().isLargeDialogMessage(notification.getContentDescription().getContentType())) { res.append(getNotificationSender(notification)); res.append(": "); res.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, res.length(), 0); } res.append(messenger.getFormatter().formatNotificationText(notification)); return res; } private String getNotificationSender(Notification pendingNotification) { String sender; if (pendingNotification.getPeer().getPeerType() == PeerType.GROUP) { sender = messenger().getUser(pendingNotification.getSender()).getName().get(); sender += "@"; sender += messenger().getGroup(pendingNotification.getPeer().getPeerId()).getName().get(); } else { sender = messenger().getUser(pendingNotification.getSender()).getName().get(); } return sender; } }