2323import android .content .Context ;
2424import android .content .Intent ;
2525import android .graphics .Bitmap ;
26+ import android .graphics .BitmapFactory ;
2627import android .os .Build ;
2728import android .os .Handler ;
2829import android .util .Log ;
2930import android .view .KeyEvent ;
30- import android .view .View ;
31- import android .widget .RemoteViews ;
3231
3332import androidx .core .app .NotificationCompat ;
33+ import androidx .media .app .NotificationCompat .MediaStyle ;
3434
3535import net .nullsum .audinaut .R ;
3636import net .nullsum .audinaut .activity .SubsonicActivity ;
@@ -68,27 +68,38 @@ public static void showPlayingNotification(final Context context, final Download
6868
6969 final boolean playing = downloadService .getPlayerState () == PlayerState .STARTED ;
7070
71- RemoteViews expandedContentView = new RemoteViews (context .getPackageName (), R .layout .notification_expanded );
72- setupViews (expandedContentView , context , song , true , playing );
73-
74- RemoteViews smallContentView = new RemoteViews (context .getPackageName (), R .layout .notification );
75- setupViews (smallContentView , context , song , false , playing );
76-
7771 Intent notificationIntent = new Intent (context , SubsonicFragmentActivity .class );
7872 notificationIntent .putExtra (Constants .INTENT_EXTRA_NAME_DOWNLOAD , true );
7973 notificationIntent .addFlags (Intent .FLAG_ACTIVITY_CLEAR_TOP );
8074
81- final Notification notification = new NotificationCompat .Builder (context , CHANNEL_PLAYING_ID )
75+ Intent cancelIntent = new Intent ("KEYCODE_MEDIA_STOP" )
76+ .setComponent (new ComponentName (context , DownloadService .class ))
77+ .putExtra (Intent .EXTRA_KEY_EVENT , new KeyEvent (KeyEvent .ACTION_UP , KeyEvent .KEYCODE_MEDIA_STOP ));
78+ int [] compactActions = new int []{0 , 1 , 2 };
79+ MediaStyle mediaStyle = new MediaStyle ()
80+ .setShowActionsInCompactView (compactActions )
81+ .setShowCancelButton (true )
82+ .setCancelButtonIntent (PendingIntent .getService (context , 0 , cancelIntent , 0 ));
83+
84+ NotificationCompat .Builder builder = new NotificationCompat .Builder (context , CHANNEL_PLAYING_ID )
8285 .setChannelId (CHANNEL_PLAYING_ID )
8386 .setSmallIcon (R .drawable .stat_notify_playing )
8487 .setContentTitle (song .getTitle ())
85- .setContentText (song .getTitle ())
88+ .setContentText (song .getArtist ())
89+ .setSubText (song .getAlbum ())
90+ .setTicker (song .getTitle ())
8691 .setOngoing (playing )
87- .setVisibility (Notification .VISIBILITY_PUBLIC )
88- .setCustomContentView (smallContentView )
89- .setCustomBigContentView (expandedContentView )
90- .setContentIntent (PendingIntent .getActivity (context , 0 , notificationIntent , 0 ))
91- .setPriority (NotificationCompat .PRIORITY_LOW ).build ();
92+ .setVisibility (NotificationCompat .VISIBILITY_PUBLIC )
93+ .setShowWhen (false )
94+ .setLargeIcon (getAlbumArt (context , song ))
95+ .setStyle (mediaStyle )
96+ .setContentIntent (PendingIntent .getActivity (context , 0 , notificationIntent , 0 ));
97+ addActions (context , builder , playing );
98+ final Notification notification = builder .build ();
99+
100+ if (playing ) {
101+ notification .flags |= Notification .FLAG_NO_CLEAR | Notification .FLAG_ONGOING_EVENT ;
102+ }
92103
93104 playShowing = true ;
94105 if (downloadForeground && downloadShowing ) {
@@ -116,13 +127,7 @@ public static void showPlayingNotification(final Context context, final Download
116127 AudinautWidgetProvider .notifyInstances (context , downloadService , playing );
117128 }
118129
119- private static void setupViews (RemoteViews rv , Context context , MusicDirectory .Entry song , boolean expanded , boolean playing ) {
120- // Use the same text for the ticker and the expanded notification
121- String title = song .getTitle ();
122- String arist = song .getArtist ();
123- String album = song .getAlbum ();
124-
125- // Set the album art.
130+ private static Bitmap getAlbumArt (Context context , MusicDirectory .Entry song ) {
126131 try {
127132 ImageLoader imageLoader = SubsonicActivity .getStaticImageLoader (context );
128133 Bitmap bitmap = null ;
@@ -131,90 +136,42 @@ private static void setupViews(RemoteViews rv, Context context, MusicDirectory.E
131136 }
132137 if (bitmap == null ) {
133138 // set default album art
134- rv . setImageViewResource ( R . id . notification_image , R .drawable .unknown_album );
139+ return BitmapFactory . decodeResource ( context . getResources () , R .drawable .unknown_album );
135140 } else {
136- imageLoader .setNowPlayingSmall (bitmap );
137- rv .setImageViewBitmap (R .id .notification_image , bitmap );
141+ return bitmap ;
138142 }
139143 } catch (Exception x ) {
140144 Log .w (TAG , "Failed to get notification cover art" , x );
141- rv .setImageViewResource (R .id .notification_image , R .drawable .unknown_album );
142- }
143-
144- // set the text for the notifications
145- rv .setTextViewText (R .id .notification_title , title );
146- rv .setTextViewText (R .id .notification_artist , arist );
147- rv .setTextViewText (R .id .notification_album , album );
148-
149- boolean persistent = Util .getPreferences (context ).getBoolean (Constants .PREFERENCES_KEY_PERSISTENT_NOTIFICATION , false );
150- if (persistent ) {
151- if (expanded ) {
152- rv .setImageViewResource (R .id .control_pause , playing ? R .drawable .notification_media_pause : R .drawable .notification_media_start );
153-
154- rv .setImageViewResource (R .id .control_previous , R .drawable .notification_media_backward );
155- rv .setImageViewResource (R .id .control_next , R .drawable .notification_media_forward );
156- } else {
157- rv .setImageViewResource (R .id .control_previous , playing ? R .drawable .notification_media_pause : R .drawable .notification_media_start );
158- rv .setImageViewResource (R .id .control_pause , R .drawable .notification_media_forward );
159- rv .setImageViewResource (R .id .control_next , R .drawable .notification_close );
160- }
161- } else {
162- // Necessary for switching back since it appears to re-use the same layout
163- rv .setImageViewResource (R .id .control_previous , R .drawable .notification_media_backward );
164- rv .setImageViewResource (R .id .control_pause , R .drawable .notification_media_pause );
165- rv .setImageViewResource (R .id .control_next , R .drawable .notification_media_forward );
145+ return BitmapFactory .decodeResource (context .getResources (), R .drawable .unknown_album );
166146 }
147+ }
167148
168- // Create actions for media buttons
149+ private static void addActions ( final Context context , final NotificationCompat . Builder builder , final boolean playing ) {
169150 PendingIntent pendingIntent ;
170- int previous = 0 , pause , next , close = 0 ;
171- if (persistent && !expanded ) {
172- pause = R .id .control_previous ;
173- next = R .id .control_pause ;
174- close = R .id .control_next ;
175- } else {
176- previous = R .id .control_previous ;
177- pause = R .id .control_pause ;
178- next = R .id .control_next ;
179- }
180151
181- if (persistent && close == 0 && expanded ) {
182- close = R .id .notification_close ;
183- rv .setViewVisibility (close , View .VISIBLE );
184- }
185-
186- if (previous > 0 ) {
187- Intent prevIntent = new Intent ("KEYCODE_MEDIA_PREVIOUS" );
188- prevIntent .setComponent (new ComponentName (context , DownloadService .class ));
189- prevIntent .putExtra (Intent .EXTRA_KEY_EVENT , new KeyEvent (KeyEvent .ACTION_UP , KeyEvent .KEYCODE_MEDIA_PREVIOUS ));
190- pendingIntent = PendingIntent .getService (context , 0 , prevIntent , 0 );
191- rv .setOnClickPendingIntent (previous , pendingIntent );
192- }
152+ Intent prevIntent = new Intent ("KEYCODE_MEDIA_PREVIOUS" );
153+ prevIntent .setComponent (new ComponentName (context , DownloadService .class ));
154+ prevIntent .putExtra (Intent .EXTRA_KEY_EVENT , new KeyEvent (KeyEvent .ACTION_UP , KeyEvent .KEYCODE_MEDIA_PREVIOUS ));
155+ pendingIntent = PendingIntent .getService (context , 0 , prevIntent , 0 );
156+ builder .addAction (R .drawable .notification_media_backward , "Previous" , pendingIntent );
193157 if (playing ) {
194158 Intent pauseIntent = new Intent ("KEYCODE_MEDIA_PLAY_PAUSE" );
195159 pauseIntent .setComponent (new ComponentName (context , DownloadService .class ));
196160 pauseIntent .putExtra (Intent .EXTRA_KEY_EVENT , new KeyEvent (KeyEvent .ACTION_UP , KeyEvent .KEYCODE_MEDIA_PLAY_PAUSE ));
197161 pendingIntent = PendingIntent .getService (context , 0 , pauseIntent , 0 );
198- rv . setOnClickPendingIntent ( pause , pendingIntent );
162+ builder . addAction ( R . drawable . notification_media_pause , "Pause" , pendingIntent );
199163 } else {
200- Intent prevIntent = new Intent ("KEYCODE_MEDIA_START " );
201- prevIntent .setComponent (new ComponentName (context , DownloadService .class ));
202- prevIntent .putExtra (Intent .EXTRA_KEY_EVENT , new KeyEvent (KeyEvent .ACTION_UP , KeyEvent .KEYCODE_MEDIA_PLAY ));
203- pendingIntent = PendingIntent .getService (context , 0 , prevIntent , 0 );
204- rv . setOnClickPendingIntent ( pause , pendingIntent );
164+ Intent playIntent = new Intent ("KEYCODE_MEDIA_PLAY " );
165+ playIntent .setComponent (new ComponentName (context , DownloadService .class ));
166+ playIntent .putExtra (Intent .EXTRA_KEY_EVENT , new KeyEvent (KeyEvent .ACTION_UP , KeyEvent .KEYCODE_MEDIA_PLAY ));
167+ pendingIntent = PendingIntent .getService (context , 0 , playIntent , 0 );
168+ builder . addAction ( R . drawable . notification_media_start , "Play" , pendingIntent );
205169 }
206170 Intent nextIntent = new Intent ("KEYCODE_MEDIA_NEXT" );
207171 nextIntent .setComponent (new ComponentName (context , DownloadService .class ));
208172 nextIntent .putExtra (Intent .EXTRA_KEY_EVENT , new KeyEvent (KeyEvent .ACTION_UP , KeyEvent .KEYCODE_MEDIA_NEXT ));
209173 pendingIntent = PendingIntent .getService (context , 0 , nextIntent , 0 );
210- rv .setOnClickPendingIntent (next , pendingIntent );
211- if (close > 0 ) {
212- Intent prevIntent = new Intent ("KEYCODE_MEDIA_STOP" );
213- prevIntent .setComponent (new ComponentName (context , DownloadService .class ));
214- prevIntent .putExtra (Intent .EXTRA_KEY_EVENT , new KeyEvent (KeyEvent .ACTION_UP , KeyEvent .KEYCODE_MEDIA_STOP ));
215- pendingIntent = PendingIntent .getService (context , 0 , prevIntent , 0 );
216- rv .setOnClickPendingIntent (close , pendingIntent );
217- }
174+ builder .addAction (R .drawable .notification_media_forward , "Next" , pendingIntent );
218175 }
219176
220177 public static void hidePlayingNotification (final Context context , final DownloadService downloadService , Handler handler ) {
0 commit comments