Update
This problem is fixed now if you link in Android Support Library revision 22.2.1 (July 2015):
Older workaround
Here's my workaround for "There is no NotificationCompat.MediaStyle in the support library".
It avoids duplicating application logic and makes it easy to back out the workaround if/when NotificationCompat supports MediaStyle
.
Purpose: This makes it easy to use the MediaStyle
in API 21+ (offering compact and expanded notification layouts, with buttons), or an ordinary notification layout on older versions of Android (just one layout, with buttons).
Note: If your goal is to put buttons on the lock screen on multiple versions of Android, you can use this approach to implement lock screen notifications for API 21+, and also implement a lock screen widget for older APIs.
How to: First, create a new notification builder compatibility package, starting with an interface to alternate underlying implementations. Crib from NotificationCompat.Builder
, stripped down to the needed features:
public interface NotificationBuilder {
public NotificationBuilder setWhen(long when);
public NotificationBuilder setUsesChronometer(boolean b);
public NotificationBuilder setSmallIcon(int icon);
// ...
/** Sets MediaStyle with setShowActionsInCompactView(). */
public NotificationBuilder setMediaStyleActionsInCompactView(int... actions);
public Notification build();
}
Second, make an implementation built on NotificationCompat.Builder
:
public class V20Builder implements NotificationBuilder {
private NotificationCompat.Builder builder;
public V20Builder(Context context) {
builder = new NotificationCompat.Builder(context);
}
@Override
public NotificationBuilder setWhen(long when) {
builder.setWhen(when);
return this;
}
@Override
public NotificationBuilder setUsesChronometer(boolean b) {
builder.setUsesChronometer(b);
return this;
}
@Override
public NotificationBuilder setSmallIcon(int icon) {
builder.setSmallIcon(icon);
return this;
}
// ...
@Override
public NotificationBuilder setMediaStyleActionsInCompactView(int... actions) {
// Noop for Android API V20-.
return this;
}
@Override
public Notification build() {
return builder.build();
}
}
Third, make an implementation built on Notification.Builder
:
@TargetApi(21)
public class V21Builder implements NotificationBuilder {
private Notification.Builder builder;
public V21Builder(Context context) {
builder = new Notification.Builder(context);
}
@Override
public NotificationBuilder setWhen(long when) {
builder.setWhen(when);
return this;
}
@Override
public NotificationBuilder setUsesChronometer(boolean b) {
builder.setUsesChronometer(b);
return this;
}
@Override
public NotificationBuilder setSmallIcon(int icon) {
builder.setSmallIcon(icon);
return this;
}
// ...
@Override
public NotificationBuilder setMediaStyleActionsInCompactView(int... actions) {
new Notification.MediaStyle(builder).setShowActionsInCompactView(actions);
return this;
}
@Override
public Notification build() {
return builder.build();
}
}
Fourth, add a factory method to instantiate the right builder:
public NotificationBuilder makeBuilder() {
if (Build.VERSION.SDK_INT >= 21) { // Load the API V21 class only if the OS can load it.
return new V21Builder(context);
}
return new V20Builder(context);
}