Part of my application consists in a custom lockscreen which needs to show notifications as normal android lockscreen does.
Everything works fine until Android 6, I used a NotificationListenerService to retrieve notification contentView and bigContentView (RemoteViews). I use them on my custom RecyclerView adapter to create a notification list with the same notifications listed by the service:
//this is called by NotificationListenerService
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
AddNotification(sbn);
}
then use the StatusBarNotification to retrieve contentView and bigContentView and apply them in my custom recycleview list views:
/**
* Add notification into recycleview
* @param sbn notification to add
*/
private void AddNotification(StatusBarNotification sbn)
{
Notification notification = sbn.getNotification();
if(notification==null) return;
if(notification.bigContentView!=null) {
//apply bigContentView to my recycleview list notification view
myListView.notificationview = notification.bigContentView.apply(myContext(), myNotificationLayout);
}
else if(notification.contentView!=null) {
//apply contentView to my recycleview list notification view
myListView.notificationview = notification.contentView.apply(myContext(), myNotificationLayout);
}
//notify recycleview of a new item inserted
notifyItemInserted(0);
}
This is no longer possible with Android 7 because starting with Android N (as stated in Android documentation), contentView and bigContentView could be null (actually they are). those were extremely useful beacuse you could replicate notification views which could also contain some complex action controls (such as media player notifications, with play/pause/stop controls for example):
Is it possible in Android 7 and above to create a view with the same content of the original notification?
How do I replicate the RemoteView behaviour? Is it possible to retrieve all the notifications information (graphic, text, icons, intents, etc)?
I got a better solution:
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static RemoteViews getBigContentView(Context context, Notification notification)
{
if(notification.bigContentView != null)
return notification.bigContentView;
else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
return Notification.Builder.recoverBuilder(context, notification).createBigContentView();
else
return null;
}
public static RemoteViews getContentView(Context context, Notification notification)
{
if(notification.contentView != null)
return notification.contentView;
else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
return Notification.Builder.recoverBuilder(context, notification).createContentView();
else
return null;
}
Whenever you reference Notification.contentView
, just call getContentView(...)
instead, and getBigContentView(...)
for Notification.bigContentView
. Your code will support android nougat+, and all android versions.
After modification, AddNotification
will be like this:
/**
* Add notification into recycleview
*
* @param sbn notification to add
*/
private void AddNotification(StatusBarNotification sbn)
{
Notification notification = sbn.getNotification();
if (notification == null) return;
RemoteViews remoteViews = getBigContentView(myContext(), notification);
if(remoteViews == null)
remoteViews = getContentView(myContext(), notification);
if (remoteViews != null)
{
//apply bigContentView to my recycleview list notification view
myListView.notificationview = remoteViews.apply(myContext(), myNotificationLayout);
}
//notify recycleview of a new item inserted
notifyItemInserted(0);
}