Support notifications on API 26+
This commit is contained in:
parent
3ae6ff3ca4
commit
2bdf230284
|
@ -1,21 +1,22 @@
|
||||||
/*
|
/*
|
||||||
This file is part of Subsonic.
|
This file is part of Subsonic.
|
||||||
Subsonic is free software: you can redistribute it and/or modify
|
Subsonic is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
Subsonic is distributed in the hope that it will be useful,
|
Subsonic is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
||||||
Copyright 2014 (C) Scott Jackson
|
Copyright 2014 (C) Scott Jackson
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.nullsum.audinaut.util;
|
package net.nullsum.audinaut.util;
|
||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
@ -28,10 +29,7 @@ import android.support.v4.app.NotificationCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import net.nullsum.audinaut.R;
|
import net.nullsum.audinaut.R;
|
||||||
import net.nullsum.audinaut.activity.SubsonicActivity;
|
import net.nullsum.audinaut.activity.SubsonicActivity;
|
||||||
|
@ -41,289 +39,305 @@ import net.nullsum.audinaut.domain.PlayerState;
|
||||||
import net.nullsum.audinaut.provider.AudinautWidgetProvider;
|
import net.nullsum.audinaut.provider.AudinautWidgetProvider;
|
||||||
import net.nullsum.audinaut.service.DownloadFile;
|
import net.nullsum.audinaut.service.DownloadFile;
|
||||||
import net.nullsum.audinaut.service.DownloadService;
|
import net.nullsum.audinaut.service.DownloadService;
|
||||||
import net.nullsum.audinaut.view.UpdateView;
|
|
||||||
|
import static android.content.Context.NOTIFICATION_SERVICE;
|
||||||
|
|
||||||
public final class Notifications {
|
public final class Notifications {
|
||||||
private static final String TAG = Notifications.class.getSimpleName();
|
private static final String TAG = Notifications.class.getSimpleName();
|
||||||
|
|
||||||
// Notification IDs.
|
public static final int NOTIFICATION_ID_PLAYING = 100;
|
||||||
public static final int NOTIFICATION_ID_PLAYING = 100;
|
public static final int NOTIFICATION_ID_DOWNLOADING = 102;
|
||||||
public static final int NOTIFICATION_ID_DOWNLOADING = 102;
|
|
||||||
|
|
||||||
private static boolean playShowing = false;
|
public static final String CHANNEL_PLAYING_ID = "playback_controls";
|
||||||
private static boolean downloadShowing = false;
|
public static final String CHANNEL_DOWNLOADING_ID = "media_download";
|
||||||
private static boolean downloadForeground = false;
|
|
||||||
private static boolean persistentPlayingShowing = false;
|
|
||||||
|
|
||||||
private final static Pair<Integer, Integer> NOTIFICATION_TEXT_COLORS = new Pair<Integer, Integer>();
|
private static boolean playShowing = false;
|
||||||
|
private static boolean downloadShowing = false;
|
||||||
|
private static boolean downloadForeground = false;
|
||||||
|
private static boolean persistentPlayingShowing = false;
|
||||||
|
|
||||||
public static void showPlayingNotification(final Context context, final DownloadService downloadService, final Handler handler, MusicDirectory.Entry song) {
|
public static void showPlayingNotification(final Context context, final DownloadService downloadService, final Handler handler, MusicDirectory.Entry song) {
|
||||||
// Set the icon, scrolling text and timestamp
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
final Notification notification = new Notification(R.drawable.stat_notify_playing, song.getTitle(), System.currentTimeMillis());
|
int importance = NotificationManager.IMPORTANCE_LOW;
|
||||||
|
|
||||||
|
NotificationChannel mChannel = new NotificationChannel(
|
||||||
|
CHANNEL_PLAYING_ID, context.getString(R.string.channel_playing_name), importance);
|
||||||
|
mChannel.setDescription(context.getString(R.string.channel_playing_description));
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(
|
||||||
|
NOTIFICATION_SERVICE);
|
||||||
|
notificationManager.createNotificationChannel(mChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean playing = downloadService.getPlayerState() == PlayerState.STARTED;
|
||||||
|
|
||||||
final boolean playing = downloadService.getPlayerState() == PlayerState.STARTED;
|
|
||||||
if(playing) {
|
|
||||||
notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
|
|
||||||
}
|
|
||||||
RemoteViews expandedContentView = new RemoteViews(context.getPackageName(), R.layout.notification_expanded);
|
RemoteViews expandedContentView = new RemoteViews(context.getPackageName(), R.layout.notification_expanded);
|
||||||
setupViews(expandedContentView ,context, song, true, playing);
|
setupViews(expandedContentView ,context, song, true, playing);
|
||||||
notification.bigContentView = expandedContentView;
|
|
||||||
notification.priority = Notification.PRIORITY_HIGH;
|
|
||||||
|
|
||||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
RemoteViews smallContentView = new RemoteViews(context.getPackageName(), R.layout.notification);
|
||||||
notification.visibility = Notification.VISIBILITY_PUBLIC;
|
setupViews(smallContentView, context, song, false, playing);
|
||||||
|
|
||||||
if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_HEADS_UP_NOTIFICATION, false) && !UpdateView.hasActiveActivity()) {
|
Intent notificationIntent = new Intent(context, SubsonicFragmentActivity.class);
|
||||||
notification.vibrate = new long[0];
|
notificationIntent.putExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD, true);
|
||||||
}
|
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
}
|
|
||||||
|
|
||||||
RemoteViews smallContentView = new RemoteViews(context.getPackageName(), R.layout.notification);
|
final Notification notification = new NotificationCompat.Builder(context, CHANNEL_PLAYING_ID)
|
||||||
setupViews(smallContentView, context, song, false, playing);
|
.setChannelId(CHANNEL_PLAYING_ID)
|
||||||
notification.contentView = smallContentView;
|
.setSmallIcon(R.drawable.stat_notify_playing)
|
||||||
|
.setContentTitle(song.getTitle())
|
||||||
|
.setContentText(song.getTitle())
|
||||||
|
.setOngoing(playing)
|
||||||
|
.setVisibility(Notification.VISIBILITY_PUBLIC)
|
||||||
|
.setCustomContentView(smallContentView)
|
||||||
|
.setCustomBigContentView(expandedContentView)
|
||||||
|
.setContentIntent(PendingIntent.getActivity(context, 0, notificationIntent, 0))
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_LOW).build();
|
||||||
|
|
||||||
Intent notificationIntent = new Intent(context, SubsonicFragmentActivity.class);
|
playShowing = true;
|
||||||
notificationIntent.putExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD, true);
|
if(downloadForeground && downloadShowing) {
|
||||||
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
downloadForeground = false;
|
||||||
notification.contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
downloadService.stopForeground(true);
|
||||||
|
showDownloadingNotification(context, downloadService, handler, downloadService.getCurrentDownloading(), downloadService.getBackgroundDownloads().size());
|
||||||
|
downloadService.startForeground(NOTIFICATION_ID_PLAYING, notification);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (playing) {
|
||||||
|
downloadService.startForeground(NOTIFICATION_ID_PLAYING, notification);
|
||||||
|
} else {
|
||||||
|
playShowing = false;
|
||||||
|
persistentPlayingShowing = true;
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
downloadService.stopForeground(false);
|
||||||
|
notificationManager.notify(NOTIFICATION_ID_PLAYING, notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
playShowing = true;
|
// Update widget
|
||||||
if(downloadForeground && downloadShowing) {
|
AudinautWidgetProvider.notifyInstances(context, downloadService, playing);
|
||||||
downloadForeground = false;
|
}
|
||||||
handler.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
downloadService.stopForeground(true);
|
|
||||||
showDownloadingNotification(context, downloadService, handler, downloadService.getCurrentDownloading(), downloadService.getBackgroundDownloads().size());
|
|
||||||
downloadService.startForeground(NOTIFICATION_ID_PLAYING, notification);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
handler.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (playing) {
|
|
||||||
downloadService.startForeground(NOTIFICATION_ID_PLAYING, notification);
|
|
||||||
} else {
|
|
||||||
playShowing = false;
|
|
||||||
persistentPlayingShowing = true;
|
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
downloadService.stopForeground(false);
|
|
||||||
notificationManager.notify(NOTIFICATION_ID_PLAYING, notification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update widget
|
private static void setupViews(RemoteViews rv, Context context, MusicDirectory.Entry song, boolean expanded, boolean playing) {
|
||||||
AudinautWidgetProvider.notifyInstances(context, downloadService, playing);
|
// Use the same text for the ticker and the expanded notification
|
||||||
}
|
String title = song.getTitle();
|
||||||
|
String arist = song.getArtist();
|
||||||
|
String album = song.getAlbum();
|
||||||
|
|
||||||
private static void setupViews(RemoteViews rv, Context context, MusicDirectory.Entry song, boolean expanded, boolean playing) {
|
// Set the album art.
|
||||||
// Use the same text for the ticker and the expanded notification
|
try {
|
||||||
String title = song.getTitle();
|
ImageLoader imageLoader = SubsonicActivity.getStaticImageLoader(context);
|
||||||
String arist = song.getArtist();
|
Bitmap bitmap = null;
|
||||||
String album = song.getAlbum();
|
if(imageLoader != null) {
|
||||||
|
bitmap = imageLoader.getCachedImage(context, song, false);
|
||||||
|
}
|
||||||
|
if (bitmap == null) {
|
||||||
|
// set default album art
|
||||||
|
rv.setImageViewResource(R.id.notification_image, R.drawable.unknown_album);
|
||||||
|
} else {
|
||||||
|
imageLoader.setNowPlayingSmall(bitmap);
|
||||||
|
rv.setImageViewBitmap(R.id.notification_image, bitmap);
|
||||||
|
}
|
||||||
|
} catch (Exception x) {
|
||||||
|
Log.w(TAG, "Failed to get notification cover art", x);
|
||||||
|
rv.setImageViewResource(R.id.notification_image, R.drawable.unknown_album);
|
||||||
|
}
|
||||||
|
|
||||||
// Set the album art.
|
// set the text for the notifications
|
||||||
try {
|
rv.setTextViewText(R.id.notification_title, title);
|
||||||
ImageLoader imageLoader = SubsonicActivity.getStaticImageLoader(context);
|
rv.setTextViewText(R.id.notification_artist, arist);
|
||||||
Bitmap bitmap = null;
|
rv.setTextViewText(R.id.notification_album, album);
|
||||||
if(imageLoader != null) {
|
|
||||||
bitmap = imageLoader.getCachedImage(context, song, false);
|
|
||||||
}
|
|
||||||
if (bitmap == null) {
|
|
||||||
// set default album art
|
|
||||||
rv.setImageViewResource(R.id.notification_image, R.drawable.unknown_album);
|
|
||||||
} else {
|
|
||||||
imageLoader.setNowPlayingSmall(bitmap);
|
|
||||||
rv.setImageViewBitmap(R.id.notification_image, bitmap);
|
|
||||||
}
|
|
||||||
} catch (Exception x) {
|
|
||||||
Log.w(TAG, "Failed to get notification cover art", x);
|
|
||||||
rv.setImageViewResource(R.id.notification_image, R.drawable.unknown_album);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the text for the notifications
|
boolean persistent = Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_PERSISTENT_NOTIFICATION, false);
|
||||||
rv.setTextViewText(R.id.notification_title, title);
|
if(persistent) {
|
||||||
rv.setTextViewText(R.id.notification_artist, arist);
|
if(expanded) {
|
||||||
rv.setTextViewText(R.id.notification_album, album);
|
rv.setImageViewResource(R.id.control_pause, playing ? R.drawable.notification_pause : R.drawable.notification_start);
|
||||||
|
|
||||||
boolean persistent = Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_PERSISTENT_NOTIFICATION, false);
|
|
||||||
if(persistent) {
|
|
||||||
if(expanded) {
|
|
||||||
rv.setImageViewResource(R.id.control_pause, playing ? R.drawable.notification_pause : R.drawable.notification_start);
|
|
||||||
|
|
||||||
rv.setImageViewResource(R.id.control_previous, R.drawable.notification_backward);
|
rv.setImageViewResource(R.id.control_previous, R.drawable.notification_backward);
|
||||||
rv.setImageViewResource(R.id.control_next, R.drawable.notification_forward);
|
rv.setImageViewResource(R.id.control_next, R.drawable.notification_forward);
|
||||||
} else {
|
} else {
|
||||||
rv.setImageViewResource(R.id.control_previous, playing ? R.drawable.notification_pause : R.drawable.notification_start);
|
rv.setImageViewResource(R.id.control_previous, playing ? R.drawable.notification_pause : R.drawable.notification_start);
|
||||||
rv.setImageViewResource(R.id.control_pause, R.drawable.notification_forward);
|
rv.setImageViewResource(R.id.control_pause, R.drawable.notification_forward);
|
||||||
rv.setImageViewResource(R.id.control_next, R.drawable.notification_close);
|
rv.setImageViewResource(R.id.control_next, R.drawable.notification_close);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Necessary for switching back since it appears to re-use the same layout
|
// Necessary for switching back since it appears to re-use the same layout
|
||||||
rv.setImageViewResource(R.id.control_previous, R.drawable.notification_backward);
|
rv.setImageViewResource(R.id.control_previous, R.drawable.notification_backward);
|
||||||
rv.setImageViewResource(R.id.control_next, R.drawable.notification_forward);
|
rv.setImageViewResource(R.id.control_next, R.drawable.notification_forward);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create actions for media buttons
|
// Create actions for media buttons
|
||||||
PendingIntent pendingIntent;
|
PendingIntent pendingIntent;
|
||||||
int previous = 0, pause = 0, next = 0, close = 0, rewind = 0, fastForward = 0;
|
int previous = 0, pause = 0, next = 0, close = 0, rewind = 0, fastForward = 0;
|
||||||
if(persistent && !expanded) {
|
if(persistent && !expanded) {
|
||||||
pause = R.id.control_previous;
|
pause = R.id.control_previous;
|
||||||
next = R.id.control_pause;
|
next = R.id.control_pause;
|
||||||
close = R.id.control_next;
|
close = R.id.control_next;
|
||||||
} else {
|
} else {
|
||||||
previous = R.id.control_previous;
|
previous = R.id.control_previous;
|
||||||
pause = R.id.control_pause;
|
pause = R.id.control_pause;
|
||||||
next = R.id.control_next;
|
next = R.id.control_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(persistent && close == 0 && expanded) {
|
if(persistent && close == 0 && expanded) {
|
||||||
close = R.id.notification_close;
|
close = R.id.notification_close;
|
||||||
rv.setViewVisibility(close, View.VISIBLE);
|
rv.setViewVisibility(close, View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(previous > 0) {
|
|
||||||
Intent prevIntent = new Intent("KEYCODE_MEDIA_PREVIOUS");
|
|
||||||
prevIntent.setComponent(new ComponentName(context, DownloadService.class));
|
|
||||||
prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PREVIOUS));
|
|
||||||
pendingIntent = PendingIntent.getService(context, 0, prevIntent, 0);
|
|
||||||
rv.setOnClickPendingIntent(previous, pendingIntent);
|
|
||||||
}
|
|
||||||
if(rewind > 0) {
|
|
||||||
Intent rewindIntent = new Intent("KEYCODE_MEDIA_REWIND");
|
|
||||||
rewindIntent.setComponent(new ComponentName(context, DownloadService.class));
|
|
||||||
rewindIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_REWIND));
|
|
||||||
pendingIntent = PendingIntent.getService(context, 0, rewindIntent, 0);
|
|
||||||
rv.setOnClickPendingIntent(rewind, pendingIntent);
|
|
||||||
}
|
|
||||||
if(pause > 0) {
|
|
||||||
if(playing) {
|
|
||||||
Intent pauseIntent = new Intent("KEYCODE_MEDIA_PLAY_PAUSE");
|
|
||||||
pauseIntent.setComponent(new ComponentName(context, DownloadService.class));
|
|
||||||
pauseIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
|
|
||||||
pendingIntent = PendingIntent.getService(context, 0, pauseIntent, 0);
|
|
||||||
rv.setOnClickPendingIntent(pause, pendingIntent);
|
|
||||||
} else {
|
|
||||||
Intent prevIntent = new Intent("KEYCODE_MEDIA_START");
|
|
||||||
prevIntent.setComponent(new ComponentName(context, DownloadService.class));
|
|
||||||
prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY));
|
|
||||||
pendingIntent = PendingIntent.getService(context, 0, prevIntent, 0);
|
|
||||||
rv.setOnClickPendingIntent(pause, pendingIntent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(next > 0) {
|
|
||||||
Intent nextIntent = new Intent("KEYCODE_MEDIA_NEXT");
|
|
||||||
nextIntent.setComponent(new ComponentName(context, DownloadService.class));
|
|
||||||
nextIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT));
|
|
||||||
pendingIntent = PendingIntent.getService(context, 0, nextIntent, 0);
|
|
||||||
rv.setOnClickPendingIntent(next, pendingIntent);
|
|
||||||
}
|
|
||||||
if(fastForward > 0) {
|
|
||||||
Intent fastForwardIntent = new Intent("KEYCODE_MEDIA_FAST_FORWARD");
|
|
||||||
fastForwardIntent.setComponent(new ComponentName(context, DownloadService.class));
|
|
||||||
fastForwardIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD));
|
|
||||||
pendingIntent = PendingIntent.getService(context, 0, fastForwardIntent, 0);
|
|
||||||
rv.setOnClickPendingIntent(fastForward, pendingIntent);
|
|
||||||
}
|
|
||||||
if(close > 0) {
|
|
||||||
Intent prevIntent = new Intent("KEYCODE_MEDIA_STOP");
|
|
||||||
prevIntent.setComponent(new ComponentName(context, DownloadService.class));
|
|
||||||
prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_STOP));
|
|
||||||
pendingIntent = PendingIntent.getService(context, 0, prevIntent, 0);
|
|
||||||
rv.setOnClickPendingIntent(close, pendingIntent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void hidePlayingNotification(final Context context, final DownloadService downloadService, Handler handler) {
|
if(previous > 0) {
|
||||||
playShowing = false;
|
Intent prevIntent = new Intent("KEYCODE_MEDIA_PREVIOUS");
|
||||||
|
prevIntent.setComponent(new ComponentName(context, DownloadService.class));
|
||||||
|
prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PREVIOUS));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, prevIntent, 0);
|
||||||
|
rv.setOnClickPendingIntent(previous, pendingIntent);
|
||||||
|
}
|
||||||
|
if(rewind > 0) {
|
||||||
|
Intent rewindIntent = new Intent("KEYCODE_MEDIA_REWIND");
|
||||||
|
rewindIntent.setComponent(new ComponentName(context, DownloadService.class));
|
||||||
|
rewindIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_REWIND));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, rewindIntent, 0);
|
||||||
|
rv.setOnClickPendingIntent(rewind, pendingIntent);
|
||||||
|
}
|
||||||
|
if(pause > 0) {
|
||||||
|
if(playing) {
|
||||||
|
Intent pauseIntent = new Intent("KEYCODE_MEDIA_PLAY_PAUSE");
|
||||||
|
pauseIntent.setComponent(new ComponentName(context, DownloadService.class));
|
||||||
|
pauseIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, pauseIntent, 0);
|
||||||
|
rv.setOnClickPendingIntent(pause, pendingIntent);
|
||||||
|
} else {
|
||||||
|
Intent prevIntent = new Intent("KEYCODE_MEDIA_START");
|
||||||
|
prevIntent.setComponent(new ComponentName(context, DownloadService.class));
|
||||||
|
prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, prevIntent, 0);
|
||||||
|
rv.setOnClickPendingIntent(pause, pendingIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(next > 0) {
|
||||||
|
Intent nextIntent = new Intent("KEYCODE_MEDIA_NEXT");
|
||||||
|
nextIntent.setComponent(new ComponentName(context, DownloadService.class));
|
||||||
|
nextIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, nextIntent, 0);
|
||||||
|
rv.setOnClickPendingIntent(next, pendingIntent);
|
||||||
|
}
|
||||||
|
if(fastForward > 0) {
|
||||||
|
Intent fastForwardIntent = new Intent("KEYCODE_MEDIA_FAST_FORWARD");
|
||||||
|
fastForwardIntent.setComponent(new ComponentName(context, DownloadService.class));
|
||||||
|
fastForwardIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, fastForwardIntent, 0);
|
||||||
|
rv.setOnClickPendingIntent(fastForward, pendingIntent);
|
||||||
|
}
|
||||||
|
if(close > 0) {
|
||||||
|
Intent prevIntent = new Intent("KEYCODE_MEDIA_STOP");
|
||||||
|
prevIntent.setComponent(new ComponentName(context, DownloadService.class));
|
||||||
|
prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_STOP));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, prevIntent, 0);
|
||||||
|
rv.setOnClickPendingIntent(close, pendingIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove notification and remove the service from the foreground
|
public static void hidePlayingNotification(final Context context, final DownloadService downloadService, Handler handler) {
|
||||||
handler.post(new Runnable() {
|
playShowing = false;
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
downloadService.stopForeground(true);
|
|
||||||
|
|
||||||
if(persistentPlayingShowing) {
|
// Remove notification and remove the service from the foreground
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
handler.post(new Runnable() {
|
||||||
notificationManager.cancel(NOTIFICATION_ID_PLAYING);
|
@Override
|
||||||
persistentPlayingShowing = false;
|
public void run() {
|
||||||
}
|
downloadService.stopForeground(true);
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get downloadNotification in foreground if playing
|
if(persistentPlayingShowing) {
|
||||||
if(downloadShowing) {
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
|
||||||
showDownloadingNotification(context, downloadService, handler, downloadService.getCurrentDownloading(), downloadService.getBackgroundDownloads().size());
|
notificationManager.cancel(NOTIFICATION_ID_PLAYING);
|
||||||
}
|
persistentPlayingShowing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Update widget
|
// Get downloadNotification in foreground if playing
|
||||||
AudinautWidgetProvider.notifyInstances(context, downloadService, false);
|
if(downloadShowing) {
|
||||||
}
|
showDownloadingNotification(context, downloadService, handler, downloadService.getCurrentDownloading(), downloadService.getBackgroundDownloads().size());
|
||||||
|
}
|
||||||
|
|
||||||
public static void showDownloadingNotification(final Context context, final DownloadService downloadService, Handler handler, DownloadFile file, int size) {
|
// Update widget
|
||||||
Intent cancelIntent = new Intent(context, DownloadService.class);
|
AudinautWidgetProvider.notifyInstances(context, downloadService, false);
|
||||||
cancelIntent.setAction(DownloadService.CANCEL_DOWNLOADS);
|
}
|
||||||
PendingIntent cancelPI = PendingIntent.getService(context, 0, cancelIntent, 0);
|
|
||||||
|
|
||||||
String currentDownloading, currentSize;
|
public static void showDownloadingNotification(final Context context, final DownloadService downloadService, Handler handler, DownloadFile file, int size) {
|
||||||
if(file != null) {
|
Intent cancelIntent = new Intent(context, DownloadService.class);
|
||||||
currentDownloading = file.getSong().getTitle();
|
cancelIntent.setAction(DownloadService.CANCEL_DOWNLOADS);
|
||||||
currentSize = Util.formatLocalizedBytes(file.getEstimatedSize(), context);
|
PendingIntent cancelPI = PendingIntent.getService(context, 0, cancelIntent, 0);
|
||||||
} else {
|
|
||||||
currentDownloading = "none";
|
|
||||||
currentSize = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationCompat.Builder builder;
|
String currentDownloading, currentSize;
|
||||||
builder = new NotificationCompat.Builder(context)
|
if(file != null) {
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download)
|
currentDownloading = file.getSong().getTitle();
|
||||||
.setContentTitle(context.getResources().getString(R.string.download_downloading_title, size))
|
currentSize = Util.formatLocalizedBytes(file.getEstimatedSize(), context);
|
||||||
.setContentText(context.getResources().getString(R.string.download_downloading_summary, currentDownloading))
|
} else {
|
||||||
.setStyle(new NotificationCompat.BigTextStyle()
|
currentDownloading = "none";
|
||||||
.bigText(context.getResources().getString(R.string.download_downloading_summary_expanded, currentDownloading, currentSize)))
|
currentSize = "0";
|
||||||
.setProgress(10, 5, true)
|
}
|
||||||
.setOngoing(true)
|
|
||||||
.addAction(R.drawable.notification_close,
|
|
||||||
context.getResources().getString(R.string.common_cancel),
|
|
||||||
cancelPI);
|
|
||||||
|
|
||||||
Intent notificationIntent = new Intent(context, SubsonicFragmentActivity.class);
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
notificationIntent.putExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW, true);
|
int importance = NotificationManager.IMPORTANCE_LOW;
|
||||||
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
NotificationChannel mChannel = new NotificationChannel(
|
||||||
builder.setContentIntent(PendingIntent.getActivity(context, 2, notificationIntent, 0));
|
CHANNEL_DOWNLOADING_ID, context.getString(R.string.channel_download_name), importance);
|
||||||
|
mChannel.setDescription(context.getString(R.string.channel_download_description));
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(
|
||||||
|
NOTIFICATION_SERVICE);
|
||||||
|
notificationManager.createNotificationChannel(mChannel);
|
||||||
|
}
|
||||||
|
|
||||||
final Notification notification = builder.build();
|
Intent notificationIntent = new Intent(context, SubsonicFragmentActivity.class);
|
||||||
downloadShowing = true;
|
notificationIntent.putExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW, true);
|
||||||
if(playShowing) {
|
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
notificationManager.notify(NOTIFICATION_ID_DOWNLOADING, notification);
|
|
||||||
} else {
|
|
||||||
downloadForeground = true;
|
|
||||||
handler.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
downloadService.startForeground(NOTIFICATION_ID_DOWNLOADING, notification);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
final Notification notification = new NotificationCompat.Builder(context, CHANNEL_DOWNLOADING_ID)
|
||||||
public static void hideDownloadingNotification(final Context context, final DownloadService downloadService, Handler handler) {
|
.setChannelId(CHANNEL_DOWNLOADING_ID)
|
||||||
downloadShowing = false;
|
.setSmallIcon(android.R.drawable.stat_sys_download)
|
||||||
if(playShowing) {
|
.setContentTitle(context.getResources().getString(R.string.download_downloading_title, size))
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
.setContentText(context.getResources().getString(R.string.download_downloading_summary, currentDownloading))
|
||||||
notificationManager.cancel(NOTIFICATION_ID_DOWNLOADING);
|
.setOngoing(true)
|
||||||
} else {
|
.addAction(R.drawable.notification_close,
|
||||||
downloadForeground = false;
|
context.getResources().getString(R.string.common_cancel),
|
||||||
handler.post(new Runnable() {
|
cancelPI)
|
||||||
@Override
|
.setContentIntent(PendingIntent.getActivity(context, 2, notificationIntent, 0))
|
||||||
public void run() {
|
.setStyle(new NotificationCompat.BigTextStyle()
|
||||||
downloadService.stopForeground(true);
|
.bigText(context.getResources().getString(R.string.download_downloading_summary_expanded, currentDownloading, currentSize)))
|
||||||
}
|
.setProgress(10, 5, true).build();
|
||||||
});
|
|
||||||
}
|
downloadShowing = true;
|
||||||
}
|
if(playShowing) {
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
notificationManager.notify(NOTIFICATION_ID_DOWNLOADING, notification);
|
||||||
|
} else {
|
||||||
|
downloadForeground = true;
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
downloadService.startForeground(NOTIFICATION_ID_DOWNLOADING, notification);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public static void hideDownloadingNotification(final Context context, final DownloadService downloadService, Handler handler) {
|
||||||
|
downloadShowing = false;
|
||||||
|
if(playShowing) {
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
notificationManager.cancel(NOTIFICATION_ID_DOWNLOADING);
|
||||||
|
} else {
|
||||||
|
downloadForeground = false;
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
downloadService.stopForeground(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,4 +359,10 @@
|
||||||
<item quantity="one">One song added to play queue.</item>
|
<item quantity="one">One song added to play queue.</item>
|
||||||
<item quantity="other">%d songs added to play queue.</item>
|
<item quantity="other">%d songs added to play queue.</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
|
<string name="channel.playing_name">Now Playing</string>
|
||||||
|
<string name="channel.playing_description">Media controls and information about the playing song.</string>
|
||||||
|
|
||||||
|
<string name="channel.download_name">Media Download</string>
|
||||||
|
<string name="channel.download_description">Displays progress for explicitly initiated downloads (ex. cache).</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue