From 7742c40ac0fff4b2e275ed6ef92be6e170e6a157 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Wed, 3 May 2023 20:41:19 +0530 Subject: [PATCH 1/5] Create individual stream notifications for convenience on Android 7.0 and later. --- .../feed/notifications/NotificationHelper.kt | 92 ++++++++++++++----- .../feed/notifications/NotificationWorker.kt | 2 +- .../schabi/newpipe/util/NavigationHelper.java | 16 +++- 3 files changed, 81 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt index dc863126e..c66b0d1c0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt @@ -1,6 +1,8 @@ package org.schabi.newpipe.local.feed.notifications +import android.app.Notification import android.app.NotificationManager +import android.app.PendingIntent import android.content.Context import android.content.Intent import android.graphics.Bitmap @@ -12,6 +14,7 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.app.PendingIntentCompat import androidx.core.content.ContextCompat +import androidx.core.content.getSystemService import androidx.preference.PreferenceManager import com.squareup.picasso.Picasso import com.squareup.picasso.Target @@ -26,23 +29,22 @@ import org.schabi.newpipe.util.PicassoHelper * Helper for everything related to show notifications about new streams to the user. */ class NotificationHelper(val context: Context) { - - private val manager = context.getSystemService( - Context.NOTIFICATION_SERVICE - ) as NotificationManager - + private val manager = context.getSystemService()!! private val iconLoadingTargets = ArrayList() /** - * Show a notification about new streams from a single channel. - * Opening the notification will open the corresponding channel page. + * Show notifications for new streams from a single channel. The individual notifications are + * expandable on Android 7.0 and later. + * + * Opening the summary notification will open the corresponding channel page. Opening the + * individual notifications will open the corresponding video. */ - fun displayNewStreamsNotification(data: FeedUpdateInfo) { - val newStreams: List = data.newStreams + fun displayNewStreamsNotifications(data: FeedUpdateInfo) { + val newStreams = data.newStreams val summary = context.resources.getQuantityString( R.plurals.new_streams, newStreams.size, newStreams.size ) - val builder = NotificationCompat.Builder( + val summaryBuilder = NotificationCompat.Builder( context, context.getString(R.string.streams_notification_channel_id) ) @@ -50,7 +52,7 @@ class NotificationHelper(val context: Context) { .setContentText( data.listInfo.relatedItems.joinToString( context.getString(R.string.enumeration_comma) - ) { x -> x.name } + ) { it.name } ) .setNumber(newStreams.size) .setBadgeIconType(NotificationCompat.BADGE_ICON_LARGE) @@ -60,16 +62,19 @@ class NotificationHelper(val context: Context) { .setColorized(true) .setAutoCancel(true) .setCategory(NotificationCompat.CATEGORY_SOCIAL) + .setGroupSummary(true) + .setGroup(data.listInfo.url) + .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY) - // Build style + // Build a summary notification for Android versions < 7.0 val style = NotificationCompat.InboxStyle() + .setSummaryText(summary) + .setBigContentTitle(data.name) newStreams.forEach { style.addLine(it.name) } - style.setSummaryText(summary) - style.setBigContentTitle(data.name) - builder.setStyle(style) + summaryBuilder.setStyle(style) - // open the channel page when clicking on the notification - builder.setContentIntent( + // open the channel page when clicking on the summary notification + summaryBuilder.setContentIntent( PendingIntentCompat.getActivity( context, data.pseudoId, @@ -84,13 +89,21 @@ class NotificationHelper(val context: Context) { // a Target is like a listener for image loading events val target = object : Target { override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) { - builder.setLargeIcon(bitmap) // set only if there is actually one - manager.notify(data.pseudoId, builder.build()) + summaryBuilder.setLargeIcon(bitmap) // set only if there is actually one + + // Show individual stream notifications + showStreamNotifications(newStreams, data.listInfo.serviceId) + // Show summary notification + manager.notify(data.pseudoId, summaryBuilder.build()) + iconLoadingTargets.remove(this) // allow it to be garbage-collected } override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) { - manager.notify(data.pseudoId, builder.build()) + // Show individual stream notifications + showStreamNotifications(newStreams, data.listInfo.serviceId) + // Show summary notification + manager.notify(data.pseudoId, summaryBuilder.build()) iconLoadingTargets.remove(this) // allow it to be garbage-collected } @@ -106,6 +119,41 @@ class NotificationHelper(val context: Context) { PicassoHelper.loadNotificationIcon(data.avatarUrl).into(target) } + private fun showStreamNotifications(newStreams: List, serviceId: Int) { + newStreams.asSequence() + .map { it to createStreamNotification(it, serviceId) } + .forEach { (stream, notification) -> + manager.notify(stream.url.hashCode(), notification) + } + } + + private fun createStreamNotification(item: StreamInfoItem, serviceId: Int): Notification { + return NotificationCompat.Builder( + context, + context.getString(R.string.streams_notification_channel_id) + ) + .setSmallIcon(R.drawable.ic_newpipe_triangle_white) + .setContentTitle(item.name) + .setContentText(item.uploaderName) + .setGroup(item.uploaderUrl) + .setColor(ContextCompat.getColor(context, R.color.ic_launcher_background)) + .setColorized(true) + .setAutoCancel(true) + .setCategory(NotificationCompat.CATEGORY_SOCIAL) + .setContentIntent( + // Open the stream link in the player when clicking on the notification. + PendingIntentCompat.getActivity( + context, + item.url.hashCode(), + NavigationHelper.getStreamIntent(context, serviceId, item.url, item.name), + PendingIntent.FLAG_UPDATE_CURRENT, + false + ) + ) + .setSilent(true) // Avoid creating noise for individual stream notifications. + .build() + } + companion object { /** * Check whether notifications are enabled on the device. @@ -124,9 +172,7 @@ class NotificationHelper(val context: Context) { fun areNotificationsEnabledOnDevice(context: Context): Boolean { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channelId = context.getString(R.string.streams_notification_channel_id) - val manager = context.getSystemService( - Context.NOTIFICATION_SERVICE - ) as NotificationManager + val manager = context.getSystemService()!! val enabled = manager.areNotificationsEnabled() val channel = manager.getNotificationChannel(channelId) val importance = channel?.importance diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt index 6b9580802..de640dbbb 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt @@ -55,7 +55,7 @@ class NotificationWorker( .map { feedUpdateInfoList -> // display notifications for each feedUpdateInfo (i.e. channel) feedUpdateInfoList.forEach { feedUpdateInfo -> - notificationHelper.displayNewStreamsNotification(feedUpdateInfo) + notificationHelper.displayNewStreamsNotifications(feedUpdateInfo) } return@map Result.success() } diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java index e212edd07..b0d7dcf73 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -563,11 +563,8 @@ public final class NavigationHelper { @Nullable final PlayQueue playQueue, final boolean switchingPlayers) { - final Intent intent = getOpenIntent(context, url, serviceId, - StreamingService.LinkType.STREAM); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Constants.KEY_TITLE, title); - intent.putExtra(VideoDetailFragment.KEY_SWITCHING_PLAYERS, switchingPlayers); + final Intent intent = getStreamIntent(context, serviceId, url, title) + .putExtra(VideoDetailFragment.KEY_SWITCHING_PLAYERS, switchingPlayers); if (playQueue != null) { final String cacheKey = SerializedCache.getInstance().put(playQueue, PlayQueue.class); @@ -680,6 +677,15 @@ public final class NavigationHelper { return getOpenIntent(context, url, serviceId, StreamingService.LinkType.CHANNEL); } + public static Intent getStreamIntent(final Context context, + final int serviceId, + final String url, + @Nullable final String title) { + return getOpenIntent(context, url, serviceId, StreamingService.LinkType.STREAM) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .putExtra(Constants.KEY_TITLE, title); + } + /** * Finish this Activity as well as all Activities running below it * and then start MainActivity. From 795bc82c7f653685e40088bddfd09d0658ab955a Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sun, 7 May 2023 18:59:29 +0530 Subject: [PATCH 2/5] Show number of new streams in the collapsed summary notification. --- .../local/feed/notifications/NotificationHelper.kt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt index c66b0d1c0..228f58a2f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt @@ -21,7 +21,6 @@ import com.squareup.picasso.Target import org.schabi.newpipe.R import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.service.FeedUpdateInfo -import org.schabi.newpipe.util.Localization import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.util.PicassoHelper @@ -48,12 +47,8 @@ class NotificationHelper(val context: Context) { context, context.getString(R.string.streams_notification_channel_id) ) - .setContentTitle(Localization.concatenateStrings(data.name, summary)) - .setContentText( - data.listInfo.relatedItems.joinToString( - context.getString(R.string.enumeration_comma) - ) { it.name } - ) + .setContentTitle(data.name) + .setContentText(summary) .setNumber(newStreams.size) .setBadgeIconType(NotificationCompat.BADGE_ICON_LARGE) .setPriority(NotificationCompat.PRIORITY_DEFAULT) @@ -68,7 +63,6 @@ class NotificationHelper(val context: Context) { // Build a summary notification for Android versions < 7.0 val style = NotificationCompat.InboxStyle() - .setSummaryText(summary) .setBigContentTitle(data.name) newStreams.forEach { style.addLine(it.name) } summaryBuilder.setStyle(style) From eeec6fd002353f9155d85e268e7741e29e6fe9ab Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 17 Jul 2023 01:26:44 +0200 Subject: [PATCH 3/5] Replace null check with use of NotificationManagerCompat.from --- .../newpipe/local/feed/notifications/NotificationHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt index 228f58a2f..94b3040a0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt @@ -28,7 +28,7 @@ import org.schabi.newpipe.util.PicassoHelper * Helper for everything related to show notifications about new streams to the user. */ class NotificationHelper(val context: Context) { - private val manager = context.getSystemService()!! + private val manager = NotificationManagerCompat.from(context) private val iconLoadingTargets = ArrayList() /** From 05cc5206659754ce14a6437bcb893bab5fd05a6f Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 17 Jul 2023 01:08:51 +0200 Subject: [PATCH 4/5] Fix pure logo The previous version was not properly vertically aligned. The default alignement from the logo is used now. --- .../ic_newpipe_triangle_white.png | Bin 450 -> 655 bytes .../ic_newpipe_triangle_white.png | Bin 270 -> 480 bytes .../ic_newpipe_triangle_white.png | Bin 465 -> 831 bytes .../ic_newpipe_triangle_white.png | Bin 823 -> 1195 bytes .../ic_newpipe_triangle_white.png | Bin 802 -> 1504 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/app/src/main/res/drawable-hdpi/ic_newpipe_triangle_white.png b/app/src/main/res/drawable-hdpi/ic_newpipe_triangle_white.png index cd3b6d182b90d9b2929e6d9605a39270b153b53f..dd36385796e69e2a480737148e44d95effdeba5a 100644 GIT binary patch delta 641 zcmV-{0)G9%1CIre8Gi-<007|tn3wMzCV_|S*E^l&Yo9;Xs0006UNklpCHqmp*!>0n5sRzVL_uCE08B|VX}u1wG&U>h)&vc4S{lXOGU zk}^QpehO58W5BmMC7nPI@J`aOCG|?0UwI~uIlfFa;@@?vM+3P~$~OTd1nM^rCEK#%S5nG3mrqWy3bxB#TxLOug$Y!9UM z$ps{74{#k=ol-IZTmdfIo@mr72qbAC@BrA=pzJYY)_Q|i8J@! b50#yN?-!Yb$uv~K00000NkvXXu0mjfA)67$ delta 435 zcmV;k0Zjgn1;PW68Gi%-002t~P!j+E0f|XOK~#9!&DJxV9zht#@z-x`vx{vzsbW{L zoz$^yql#_YcGASQaa#QD^H#gl-E*^t|5NXG$1^@WD(@kpR3N(-PyrS)hiU|Mp`sk; z7iSqwFmQap>E(Gw8rwk>RJ_I)Zxqm@ZLOPIx8LXf{Y9SK? zTj6?=lYkt$%_bfa=fZ5B(U9B(WY9$#Qkum)Cs7&x4OAlsei`J$Pb;?b2@5CB8BKX2 zGALFd#&MVgoLHQr8>I=#pjhQ%C08+V@}2dxCa)BVRbAHb7Iz*qgX%=2kdLekWQV#a zI7%OKNTFMzCV_|S*E^l&Yo9;Xs0004PNklY5WcrHiBXxL4O++R7B81f}lk@i5Bj{ zqa^w~Yqs!IGxyFt|GC2qOm8q4n54E$)O{mBlIbLSCkDU_UM9JbWZNVFFog?4(1|3y z%?6CL2lwzW$-zkgMw-KNl3Pi3ZYJOpR)^z0PUA(AQ%U|>-v+RZ{kV_s!`Lp|!P6wO z{|Zo5AFApoW`D8RNFBoCBnwG)j}2&m7I6e8u`&$za2#)v%qN)|8!&{dRn-Cx;C3Um z6<6^r$=uk0hNiLJwS9|sqe;K3Ymyzff^&Y|;456Lst3*WtpQ2;IE!o8-bj7HJZ@Ii zx8Li!bZ`vU8}l{X#pSA6S-+$kpm`iiIA2vyx)in1XG&bc;Wp-U>);V)s_JW(9kl_x zhpKwr#dxGY9nnWWU+kH2j7Qq2gXh>+RjV81TdViq|0;d}kNjlqY9K0M$uEK~#9!wbLa~1~42z@jvd+kcLae`eB_! zBcX{zf*#1Yd&k}S9q#V*!}TG%5w}l&{mmyXA{Kw=f+ji$5XaFCTvAQAD{8;1z<#vl&0?fe=e8^{#FO*$M z@ihhtb=;!OkYEoQ{sR~_2KZ9M3fd+m#w8KR8lNbi)L1r640mV)BwLS_RFr+PM6(7D zloKi9Sdc(3F`_sW_~PsM2Pzgv(M%^n;yB{)7w`B6;m1RVwC3A@00000NkvXXu0mjf DCn<1z diff --git a/app/src/main/res/drawable-xhdpi/ic_newpipe_triangle_white.png b/app/src/main/res/drawable-xhdpi/ic_newpipe_triangle_white.png index 5fe229a962300eaa51cb4e19afabfb81036e445a..a875fac86f2ed3ccc07fccb8b09ba0e105ec45ab 100644 GIT binary patch delta 819 zcmV-31I+x<1HT548Gi-<00374`G)`i010qNS#tmY2NnPT2NnV2nri+4000?uMObuG zZ)S9NVRB^vcXxL#X>MzCV_|S*E^l&Yo9;Xs0008aNkls$j z$buFMN{kj86lKlK?9QD{AYVKGJ?H#8_ug|avlSg39gJow%UwXJj2S35i3~^@afXu? z)GDb>($pZ;6hTr0lYkcBwWO^9>PbwoQ(``FNzz?O%hN04v05X$DTqz!l(S3|#~8O45Ew6VphXmVq9i7T5-S zjL=R7jsSgWbo11vknKU+oxl>{Jn$o8$O7`+{I;Z;Vt@0dz6NaPZ0`V80uN#gsRv#T zb@ORS^95VPwx8Kv2W$fRBjnZOyLqpq?Mb?M@LkCE4PYs782A<;p9fq3x+SfS6F-w} z)bi83)DX(MnJSQtZ|1C9diwg;ocK@CW%1=`8a_b3K{i$JUGT-+Q% z3`m*<90VGHaWRJ619sVtbE5r=P;cNmus(*aAAi_m`&zMyLT#hf5zoH^XMkm;6c1(C zMuD3^lkKQZ9E&UsyajgKj&l}@O%?{e0w;juwxdp?i3x4sCeUa*>ON33p$t3+_SwE4 zDE@DP7_i+KB5ol@+!vRmq+y^NxRXMhqA0~c4%iK>vE7?eJ&7r14GaM1fCIKar(92B xk}Mi{1k~Do6{478s2KaJL75pdP;N%OfnNn{#dNWLO0)m~002ovPDHLkV1guOUoZdw delta 450 zcmV;z0X_b|2GIkM8Gi%-008|9F$@3z0hmcdK~#9!?ASB77(o<3;TzkwZPl@jCU(jg zP29w`-G8xd+qUg2PE@^bwwt-n=l1)rB`8l~19Ff}7pTJv29ZM(0C+-GT>v~bP)QR2 zfKg=A1p=O{PoecJXAf#gemx<~;ok(pD2ts<)5D>azt8v!_fXukC4? zgB66BdF-aJ?S+_EKxmY4CxTW7TAoL$1+MFhzno~G5f_4nj(k} z@P#g8Gi-<0033(vqt~`010qNS#tmY3ZVc13ZVfe-hMzCV_|S*E^l&Yo9;Xs000CyNkl`hQBt-#65 zAuXgLGD1oVql;Rnhjk82+034^Z)=^{AI#fX|MllPd$09ddmpB6WMqVfshJhKfz)XP zWzY!9pb?ZoBPfGLPzI$4l5~fpQ_8578f9HU>wyVLca~Hy8OprHE(hL}v{};P66;2# ziZy5@uuIagq<=Fjs9!5pEz)y9tG^MQ@PN0P3sc&znNdwo4k7 zbbd{9mO`DE{w!b>@VTTRNwaI5J2x@bhO>d^fpJL#5$5lTn2YBUV5_9JC0!b^k7-F^ zcNqjelk`N2X*>l%0H*ut95)|$71$Acdq%Aig`hinf4R|D_otnu$O zeo|@OO*3Jw*xm(P58MTOle5e@gfzZW(u%Tr`!Av_(zaW+-vX`zo&}EPEVUGPSJIfI zi%M&75`R&5G22IMZvYkp@8m4g2iy&O(N5!YOKXrswt3t8Z4UxB1N(B8Ih~Nk_ei?6 ztlp9k)WP;{fi=u9jrWwG4z@oARsau@e-WQYNaH&s z&70~&Jt?TY*scN|CIrR2j05XzADZd|Jts&~Kd_y!=w6Vs%#VbuwcPdx(|xcf-c12W zx_=OO61a!_U+i(-`05w`UrKc_hW zJOYf_?s`E_QjnxefTsxyabAuBF9VO-{v~gbqy$Mi71+@JEAkR?6EI}^%c4CcBS_M1 zgxhIBfin9E+jib(OD7OrkfepcFmOwOGJn4U&jHWa{-cz}+C&v3X#p@%ppO>t2Jn#W z@5<_HGO@3qxdnRI4Lo4`y%PI5fu2j!z+plPURJdnh<^oj!(YJbzzcGz1nnf; zP9N4iaq73&_k<^j*Tj$m>0Uv{fS2gvP+1iz3fe+AR8GWh1kw`pE#cfW8oQCnq<7pJx3jab^`;pzp7!b z(y3C=PlQ8de;tR)s;FX-ZUL`R^P#dT$`&*Z+#l=QR0U<-Vw2xg{%_INKpb?b8-<@GPw#20i>Hq)$07*qoM6N<$g7yO_ APXGV_ delta 811 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 U+7C1lL;wH)07*qoM6N<$f;=Z~#Q*>R From cb00c57009dd79b44d8ea0bc8ccb0a7672991a36 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Wed, 19 Jul 2023 05:21:30 +0530 Subject: [PATCH 5/5] Set channel icon for stream notifications --- .../feed/notifications/NotificationHelper.kt | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt index 94b3040a0..5aca3ad26 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt @@ -83,10 +83,12 @@ class NotificationHelper(val context: Context) { // a Target is like a listener for image loading events val target = object : Target { override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) { - summaryBuilder.setLargeIcon(bitmap) // set only if there is actually one + // set channel icon only if there is actually one (for Android versions < 7.0) + summaryBuilder.setLargeIcon(bitmap) - // Show individual stream notifications - showStreamNotifications(newStreams, data.listInfo.serviceId) + // Show individual stream notifications, set channel icon only if there is actually + // one + showStreamNotifications(newStreams, data.listInfo.serviceId, bitmap) // Show summary notification manager.notify(data.pseudoId, summaryBuilder.build()) @@ -95,7 +97,7 @@ class NotificationHelper(val context: Context) { override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) { // Show individual stream notifications - showStreamNotifications(newStreams, data.listInfo.serviceId) + showStreamNotifications(newStreams, data.listInfo.serviceId, null) // Show summary notification manager.notify(data.pseudoId, summaryBuilder.build()) iconLoadingTargets.remove(this) // allow it to be garbage-collected @@ -113,20 +115,28 @@ class NotificationHelper(val context: Context) { PicassoHelper.loadNotificationIcon(data.avatarUrl).into(target) } - private fun showStreamNotifications(newStreams: List, serviceId: Int) { - newStreams.asSequence() - .map { it to createStreamNotification(it, serviceId) } - .forEach { (stream, notification) -> - manager.notify(stream.url.hashCode(), notification) - } + private fun showStreamNotifications( + newStreams: List, + serviceId: Int, + channelIcon: Bitmap? + ) { + for (stream in newStreams) { + val notification = createStreamNotification(stream, serviceId, channelIcon) + manager.notify(stream.url.hashCode(), notification) + } } - private fun createStreamNotification(item: StreamInfoItem, serviceId: Int): Notification { + private fun createStreamNotification( + item: StreamInfoItem, + serviceId: Int, + channelIcon: Bitmap? + ): Notification { return NotificationCompat.Builder( context, context.getString(R.string.streams_notification_channel_id) ) .setSmallIcon(R.drawable.ic_newpipe_triangle_white) + .setLargeIcon(channelIcon) .setContentTitle(item.name) .setContentText(item.uploaderName) .setGroup(item.uploaderUrl)