diff --git a/src/ch/blinkenlights/android/medialibrary/MediaScanner.java b/src/ch/blinkenlights/android/medialibrary/MediaScanner.java
index c6aec0d5..28427c8f 100644
--- a/src/ch/blinkenlights/android/medialibrary/MediaScanner.java
+++ b/src/ch/blinkenlights/android/medialibrary/MediaScanner.java
@@ -12,16 +12,15 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * along with this program. If not, see .
*/
package ch.blinkenlights.android.medialibrary;
import ch.blinkenlights.android.vanilla.R;
+import ch.blinkenlights.android.vanilla.NotificationHelper;
import android.app.Notification;
-import android.app.NotificationManager;
-
import android.content.Context;
import android.content.ContentValues;
import android.content.SharedPreferences;
@@ -70,6 +69,10 @@ public class MediaScanner implements Handler.Callback {
* True if we must do a full cleanup of orphaned entries after the scan finished.
*/
private boolean mPendingCleanup;
+ /**
+ * Our NotificationHelper instance.
+ */
+ private NotificationHelper mNotificationHelper;
/**
* Timestamp in half-seconds since last notification
*/
@@ -78,6 +81,8 @@ public class MediaScanner implements Handler.Callback {
* The id we are using for the scan notification
*/
private static final int NOTIFICATION_ID = 56162;
+ private static final String NOTIFICATION_CHANNEL = "Scanner";
+
MediaScanner(Context context, MediaLibraryBackend backend) {
mContext = context;
@@ -87,6 +92,7 @@ public class MediaScanner implements Handler.Callback {
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper(), this);
mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VanillaMusicIndexerLock");
+ mNotificationHelper = new NotificationHelper(context, NOTIFICATION_CHANNEL, context.getString(R.string.media_stats_progress));
// the content observer to use
ContentObserver mObserver = new ContentObserver(null) {
@@ -265,7 +271,6 @@ public class MediaScanner implements Handler.Callback {
*/
private void updateNotification(boolean visible) {
MediaLibrary.ScanProgress progress = describeScanProgress();
- NotificationManager manager = (NotificationManager) mContext.getSystemService(mContext.NOTIFICATION_SERVICE);
if (visible) {
int nowTime = (int)(SystemClock.uptimeMillis() / 500);
@@ -275,20 +280,20 @@ public class MediaScanner implements Handler.Callback {
String title = mContext.getResources().getString(R.string.media_library_scan_running);
String content = progress.lastFile;
- Notification notification = new Notification.Builder(mContext)
+ Notification notification = mNotificationHelper.getNewBuilder(mContext)
.setProgress(progress.total, progress.seen, false)
.setContentTitle(title)
.setContentText(content)
.setSmallIcon(icon)
.setOngoing(true)
.getNotification(); // build() is API 16 :-/
- manager.notify(NOTIFICATION_ID, notification);
+ mNotificationHelper.notify(NOTIFICATION_ID, notification);
}
if (!mWakeLock.isHeld())
mWakeLock.acquire();
} else {
- manager.cancel(NOTIFICATION_ID);
+ mNotificationHelper.cancel(NOTIFICATION_ID);
if (mWakeLock.isHeld())
mWakeLock.release();
diff --git a/src/ch/blinkenlights/android/vanilla/NotificationHelper.java b/src/ch/blinkenlights/android/vanilla/NotificationHelper.java
new file mode 100644
index 00000000..e84141df
--- /dev/null
+++ b/src/ch/blinkenlights/android/vanilla/NotificationHelper.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 Adrian Ulrich
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package ch.blinkenlights.android.vanilla;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+
+public class NotificationHelper {
+ /**
+ * The notification manager instance we are using.
+ */
+ private NotificationManager mNotificationManager;
+ /**
+ * The name of the channel to use for these notifications.
+ */
+ private String mChannelId;
+
+ /**
+ * Creates and returns a new NotificationHelper.
+ *
+ * @param context the context to use.
+ * @param channelId the ID of the notification channel to create.
+ * @param name the user visible name of the channel.
+ */
+ public NotificationHelper(Context context, String channelId, String name) {
+ mNotificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
+ mChannelId = channelId;
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel channel = new NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_DEFAULT);
+ mNotificationManager.createNotificationChannel(channel);
+ }
+ }
+
+ /**
+ * Returns a new Notification.Builder.
+ *
+ * @param context the context to use
+ */
+ public Notification.Builder getNewBuilder(Context context) {
+ Notification.Builder builder;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ builder = new Notification.Builder(context, mChannelId);
+ } else {
+ builder = new Notification.Builder(context);
+ }
+ return builder;
+ }
+
+ /**
+ * Retruns a new Notification.
+ *
+ * @param context the context to use.
+ */
+ public Notification getNewNotification(Context context) {
+ return getNewBuilder(context).getNotification(); // build() is API16.
+ }
+
+ /**
+ * Post a notification to be shown in the status bar.
+ *
+ * @param id the id of this notification.
+ * @param notification the notification to display.
+ */
+ public void notify(int id, Notification notification) {
+ mNotificationManager.notify(id, notification);
+ }
+
+ /**
+ * Cancels a notification.
+ *
+ * @param id the id to cancel
+ */
+ public void cancel(int id) {
+ mNotificationManager.cancel(id);
+ }
+}
diff --git a/src/ch/blinkenlights/android/vanilla/PlaybackService.java b/src/ch/blinkenlights/android/vanilla/PlaybackService.java
index 79c85d86..534b7dd0 100644
--- a/src/ch/blinkenlights/android/vanilla/PlaybackService.java
+++ b/src/ch/blinkenlights/android/vanilla/PlaybackService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2015 Adrian Ulrich
+ * Copyright (C) 2012-2017 Adrian Ulrich
* Copyright (C) 2010, 2011 Christopher Eby
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -26,7 +26,6 @@ package ch.blinkenlights.android.vanilla;
import ch.blinkenlights.android.medialibrary.MediaLibrary;
import android.app.Notification;
-import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.backup.BackupManager;
@@ -96,6 +95,7 @@ public final class PlaybackService extends Service
private static final int STATE_VERSION = 6;
private static final int NOTIFICATION_ID = 2;
+ private static final String NOTIFICATION_CHANNEL = "Playback";
/**
* Rewind song if we already played more than 2.5 sec
@@ -319,6 +319,10 @@ public final class PlaybackService extends Service
* {@link PlaybackService#createNotificationAction(SharedPreferences)}.
*/
private PendingIntent mNotificationAction;
+ /**
+ * Notification helper instance.
+ */
+ private NotificationHelper mNotificationHelper;
private Looper mLooper;
private Handler mHandler;
@@ -327,7 +331,6 @@ public final class PlaybackService extends Service
private boolean mMediaPlayerInitialized;
private boolean mMediaPlayerAudioFxActive;
private PowerManager.WakeLock mWakeLock;
- private NotificationManager mNotificationManager;
private AudioManager mAudioManager;
/**
* The SensorManager service.
@@ -443,7 +446,7 @@ public final class PlaybackService extends Service
mBastpUtil = new BastpUtil();
mReadahead = new ReadaheadThread();
- mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+ mNotificationHelper = new NotificationHelper(this, NOTIFICATION_CHANNEL, getString(R.string.app_name));
mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
SharedPreferences settings = getSettings(this);
@@ -1142,9 +1145,9 @@ public final class PlaybackService extends Service
private void updateNotification()
{
if ((mForceNotificationVisible || mNotificationMode == ALWAYS || mNotificationMode == WHEN_PLAYING && (mState & FLAG_PLAYING) != 0) && mCurrentSong != null)
- mNotificationManager.notify(NOTIFICATION_ID, createNotification(mCurrentSong, mState, mNotificationMode));
+ mNotificationHelper.notify(NOTIFICATION_ID, createNotification(mCurrentSong, mState, mNotificationMode));
else
- mNotificationManager.cancel(NOTIFICATION_ID);
+ mNotificationHelper.cancel(NOTIFICATION_ID);
}
/**
@@ -2043,7 +2046,7 @@ public final class PlaybackService extends Service
}
/**
- * Create a song notification. Call through the NotificationManager to
+ * Create a song notification. Call through the NotificationHelper to
* display it.
*
* @param song The Song to display information about.
@@ -2101,7 +2104,7 @@ public final class PlaybackService extends Service
expanded.setTextViewText(R.id.album, song.album);
expanded.setTextViewText(R.id.artist, song.artist);
- Notification notification = new Notification();
+ Notification notification = mNotificationHelper.getNewNotification(getApplicationContext());
notification.contentView = views;
notification.icon = R.drawable.status_icon;
notification.flags |= Notification.FLAG_ONGOING_EVENT;