Swipeable classic notification (#244)

* Made notification swipeable when not playing not swipeable when playing. Removed "X" close button

* Fixed music stop on tap and on app close

* Refactor notification classes
This commit is contained in:
Lincoln 2017-08-14 23:04:59 -04:00 committed by Eugene Cheung
commit 41b81ce14c
4 changed files with 54 additions and 104 deletions

View file

@ -1,17 +1,55 @@
package com.kabouzeid.gramophone.service.notification; package com.kabouzeid.gramophone.service.notification;
import android.app.Notification;
import android.app.NotificationManager;
import com.kabouzeid.gramophone.service.MusicService; import com.kabouzeid.gramophone.service.MusicService;
/** import static android.content.Context.NOTIFICATION_SERVICE;
* @author Karim Abou Zeid (kabouzeid)
*/
public interface PlayingNotification { public abstract class PlayingNotification {
int NOTIFICATION_ID = 1;
void init(MusicService service); private static final int NOTIFICATION_ID = 1;
private static final int NOTIFY_MODE_FOREGROUND = 1;
private static final int NOTIFY_MODE_BACKGROUND = 0;
void update(); private int notifyMode = NOTIFY_MODE_BACKGROUND;
void stop(); private NotificationManager notificationManager;
protected MusicService service;
boolean stopped;
public synchronized void init(MusicService service) {
this.service = service;
notificationManager = (NotificationManager) service.getSystemService(NOTIFICATION_SERVICE);
}
abstract public void update();
public synchronized void stop() {
stopped = true;
service.stopForeground(true);
notificationManager.cancel(NOTIFICATION_ID);
}
void updateNotifyModeAndPostNotification(Notification notification) {
int newNotifyMode;
if (service.isPlaying()) {
newNotifyMode = NOTIFY_MODE_FOREGROUND;
} else {
newNotifyMode = NOTIFY_MODE_BACKGROUND;
}
if (notifyMode != newNotifyMode && newNotifyMode == NOTIFY_MODE_BACKGROUND) {
service.stopForeground(false);
}
if (newNotifyMode == NOTIFY_MODE_FOREGROUND) {
service.startForeground(NOTIFICATION_ID, notification);
} else if (newNotifyMode == NOTIFY_MODE_BACKGROUND) {
notificationManager.notify(NOTIFICATION_ID, notification);
}
notifyMode = newNotifyMode;
}
} }

View file

@ -1,9 +1,5 @@
package com.kabouzeid.gramophone.service.notification; package com.kabouzeid.gramophone.service.notification;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ComponentName; import android.content.ComponentName;
@ -36,19 +32,10 @@ import com.kabouzeid.gramophone.util.PhonographColorUtil;
import com.kabouzeid.gramophone.util.PreferenceUtil; import com.kabouzeid.gramophone.util.PreferenceUtil;
import com.kabouzeid.gramophone.util.Util; import com.kabouzeid.gramophone.util.Util;
public class PlayingNotificationImpl implements PlayingNotification { public class PlayingNotificationImpl extends PlayingNotification {
private MusicService service;
private Target<BitmapPaletteWrapper> target; private Target<BitmapPaletteWrapper> target;
private boolean stopped;
@Override
public synchronized void init(MusicService service) {
this.service = service;
}
@Override @Override
public synchronized void update() { public synchronized void update() {
stopped = false; stopped = false;
@ -81,16 +68,19 @@ public class PlayingNotificationImpl implements PlayingNotification {
Intent action = new Intent(service, MainActivity.class); Intent action = new Intent(service, MainActivity.class);
action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent openAppPendingIntent = PendingIntent.getActivity(service, 0, action, 0); final PendingIntent clickIntent = PendingIntent.getActivity(service, 0, action, 0);
final PendingIntent deleteIntent = buildPendingIntent(service, MusicService.ACTION_QUIT, null);
final Notification notification = new NotificationCompat.Builder(service) final Notification notification = new NotificationCompat.Builder(service)
.setSmallIcon(R.drawable.ic_notification) .setSmallIcon(R.drawable.ic_notification)
.setContentIntent(openAppPendingIntent) .setContentIntent(clickIntent)
.setDeleteIntent(deleteIntent)
.setCategory(NotificationCompat.CATEGORY_SERVICE) .setCategory(NotificationCompat.CATEGORY_SERVICE)
.setPriority(NotificationCompat.PRIORITY_MAX) .setPriority(NotificationCompat.PRIORITY_MAX)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContent(notificationLayout) .setContent(notificationLayout)
.setCustomBigContentView(notificationLayoutBig) .setCustomBigContentView(notificationLayoutBig)
.setOngoing(isPlaying)
.build(); .build();
final int bigNotificationImageSize = service.getResources().getDimensionPixelSize(R.dimen.notification_big_image_size); final int bigNotificationImageSize = service.getResources().getDimensionPixelSize(R.dimen.notification_big_image_size);
@ -132,7 +122,7 @@ public class PlayingNotificationImpl implements PlayingNotification {
if (stopped) if (stopped)
return; // notification has been stopped before loading was finished return; // notification has been stopped before loading was finished
service.startForeground(NOTIFICATION_ID, notification); updateNotifyModeAndPostNotification(notification);
} }
private void setBackgroundColor(int color) { private void setBackgroundColor(int color) {
@ -147,7 +137,6 @@ public class PlayingNotificationImpl implements PlayingNotification {
Bitmap prev = createBitmap(Util.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, primary), 1.5f); Bitmap prev = createBitmap(Util.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, primary), 1.5f);
Bitmap next = createBitmap(Util.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, primary), 1.5f); Bitmap next = createBitmap(Util.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, primary), 1.5f);
Bitmap playPause = createBitmap(Util.getTintedVectorDrawable(service, isPlaying ? R.drawable.ic_pause_white_24dp : R.drawable.ic_play_arrow_white_24dp, primary), 1.5f); Bitmap playPause = createBitmap(Util.getTintedVectorDrawable(service, isPlaying ? R.drawable.ic_pause_white_24dp : R.drawable.ic_play_arrow_white_24dp, primary), 1.5f);
Bitmap close = createBitmap(Util.getTintedVectorDrawable(service, R.drawable.ic_close_white_24dp, secondary), 1f);
notificationLayout.setTextColor(R.id.title, primary); notificationLayout.setTextColor(R.id.title, primary);
notificationLayout.setTextColor(R.id.text, secondary); notificationLayout.setTextColor(R.id.text, secondary);
@ -161,19 +150,12 @@ public class PlayingNotificationImpl implements PlayingNotification {
notificationLayoutBig.setImageViewBitmap(R.id.action_prev, prev); notificationLayoutBig.setImageViewBitmap(R.id.action_prev, prev);
notificationLayoutBig.setImageViewBitmap(R.id.action_next, next); notificationLayoutBig.setImageViewBitmap(R.id.action_next, next);
notificationLayoutBig.setImageViewBitmap(R.id.action_play_pause, playPause); notificationLayoutBig.setImageViewBitmap(R.id.action_play_pause, playPause);
notificationLayoutBig.setImageViewBitmap(R.id.action_quit, close);
} }
}); });
} }
}); });
} }
@Override
public synchronized void stop() {
stopped = true;
service.stopForeground(true);
}
private void linkButtons(final RemoteViews notificationLayout, final RemoteViews notificationLayoutBig) { private void linkButtons(final RemoteViews notificationLayout, final RemoteViews notificationLayoutBig) {
PendingIntent pendingIntent; PendingIntent pendingIntent;
@ -193,10 +175,6 @@ public class PlayingNotificationImpl implements PlayingNotification {
pendingIntent = buildPendingIntent(service, MusicService.ACTION_SKIP, serviceName); pendingIntent = buildPendingIntent(service, MusicService.ACTION_SKIP, serviceName);
notificationLayout.setOnClickPendingIntent(R.id.action_next, pendingIntent); notificationLayout.setOnClickPendingIntent(R.id.action_next, pendingIntent);
notificationLayoutBig.setOnClickPendingIntent(R.id.action_next, pendingIntent); notificationLayoutBig.setOnClickPendingIntent(R.id.action_next, pendingIntent);
// Quit
pendingIntent = buildPendingIntent(service, MusicService.ACTION_QUIT, serviceName);
notificationLayoutBig.setOnClickPendingIntent(R.id.action_quit, pendingIntent);
} }
private PendingIntent buildPendingIntent(Context context, final String action, final ComponentName serviceName) { private PendingIntent buildPendingIntent(Context context, final String action, final ComponentName serviceName) {

View file

@ -1,7 +1,5 @@
package com.kabouzeid.gramophone.service.notification; package com.kabouzeid.gramophone.service.notification;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
@ -25,32 +23,11 @@ import com.kabouzeid.gramophone.service.MusicService;
import com.kabouzeid.gramophone.ui.activities.MainActivity; import com.kabouzeid.gramophone.ui.activities.MainActivity;
import com.kabouzeid.gramophone.util.PreferenceUtil; import com.kabouzeid.gramophone.util.PreferenceUtil;
import static android.content.Context.NOTIFICATION_SERVICE;
import static com.kabouzeid.gramophone.service.MusicService.ACTION_REWIND; import static com.kabouzeid.gramophone.service.MusicService.ACTION_REWIND;
import static com.kabouzeid.gramophone.service.MusicService.ACTION_SKIP; import static com.kabouzeid.gramophone.service.MusicService.ACTION_SKIP;
import static com.kabouzeid.gramophone.service.MusicService.ACTION_TOGGLE_PAUSE; import static com.kabouzeid.gramophone.service.MusicService.ACTION_TOGGLE_PAUSE;
/** public class PlayingNotificationImpl24 extends PlayingNotification {
* @author Karim Abou Zeid (kabouzeid)
*/
public class PlayingNotificationImpl24 implements PlayingNotification {
private static final int NOTIFY_MODE_FOREGROUND = 1;
private static final int NOTIFY_MODE_BACKGROUND = 0;
private MusicService service;
private NotificationManager notificationManager;
private int notifyMode = NOTIFY_MODE_BACKGROUND;
private boolean stopped;
@Override
public synchronized void init(MusicService service) {
this.service = service;
notificationManager = (NotificationManager) service.getSystemService(NOTIFICATION_SERVICE);
}
@Override @Override
public synchronized void update() { public synchronized void update() {
@ -140,35 +117,6 @@ public class PlayingNotificationImpl24 implements PlayingNotification {
final ComponentName serviceName = new ComponentName(service, MusicService.class); final ComponentName serviceName = new ComponentName(service, MusicService.class);
Intent intent = new Intent(action); Intent intent = new Intent(action);
intent.setComponent(serviceName); intent.setComponent(serviceName);
return PendingIntent.getService(service, 0, intent, 0); return PendingIntent.getService(service, 0, intent, 0);
} }
private void updateNotifyModeAndPostNotification(Notification notification) {
int newNotifyMode;
if (service.isPlaying()) {
newNotifyMode = NOTIFY_MODE_FOREGROUND;
} else {
newNotifyMode = NOTIFY_MODE_BACKGROUND;
}
if (notifyMode != newNotifyMode && newNotifyMode == NOTIFY_MODE_BACKGROUND) {
service.stopForeground(false);
}
if (newNotifyMode == NOTIFY_MODE_FOREGROUND) {
service.startForeground(NOTIFICATION_ID, notification);
} else if (newNotifyMode == NOTIFY_MODE_BACKGROUND) {
notificationManager.notify(NOTIFICATION_ID, notification);
}
notifyMode = newNotifyMode;
}
@Override
public synchronized void stop() {
stopped = true;
service.stopForeground(true);
notificationManager.cancel(NOTIFICATION_ID);
}
} }

View file

@ -36,18 +36,6 @@
android:scaleType="centerCrop" android:scaleType="centerCrop"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<ImageButton
android:id="@+id/action_quit"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_margin="2dp"
android:background="@drawable/notification_selector"
android:padding="6dp"
android:scaleType="fitCenter"
tools:ignore="ContentDescription" />
<LinearLayout <LinearLayout
android:id="@+id/media_titles" android:id="@+id/media_titles"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -57,9 +45,7 @@
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_toEndOf="@id/image" android:layout_toEndOf="@id/image"
android:layout_toLeftOf="@id/action_quit"
android:layout_toRightOf="@id/image" android:layout_toRightOf="@id/image"
android:layout_toStartOf="@id/action_quit"
android:minHeight="@dimen/notification_large_icon_height" android:minHeight="@dimen/notification_large_icon_height"
android:orientation="vertical"> android:orientation="vertical">