【问题标题】:Notification contentView and bigContentView are null in Android 7Android 7 中的通知 contentView 和 bigContentView 为空
【发布时间】:2017-08-25 12:40:11
【问题描述】:

我的应用程序的一部分包含一个自定义锁屏,它需要像普通的 android 锁屏一样显示通知。

在 Android 6 之前一切正常,我使用 NotificationListenerService 来检索通知 contentView 和 bigContentView (RemoteViews)。我在我的自定义 RecyclerView 适配器上使用它们来创建一个通知列表,其中包含服务列出的相同通知:

//this is called by NotificationListenerService
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
    AddNotification(sbn);
}

然后使用 StatusBarNotification 检索 contentView 和 bigContentView 并将它们应用到我的自定义 recycleview 列表视图中:

/**
* 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);
}

这在 Android 7 中不再可能,因为从 Android N 开始(如 Android 文档中所述),contentView 和 bigContentView 可能为空(实际上它们是)。 这些非常有用,因为您可以复制通知视图,其中还可能包含一些复杂的操作控件(例如媒体播放器通知,例如带有播放/暂停/停止控件):

media player notification

是否可以在 Android 7 及更高版本中创建与原始通知内容相同的视图?

如何复制 RemoteView 行为?是否可以检索所有通知信息(图形、文本、图标、意图等)?

【问题讨论】:

  • 那么您在这里使用了什么解决方案?

标签: android notifications lockscreen remoteview


【解决方案1】:

我有一个更好的解决方案:

@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;
}

每当您引用Notification.contentView 时,只需调用getContentView(...),并使用getBigContentView(...) 调用Notification.bigContentView。您的代码将支持 android nougat+ 和所有 android 版本。

修改后AddNotification会是这样的:

/**
 * 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);
}

【讨论】:

  • 我花了将近一周的时间试图找到解决方案,然后花了一个月的时间创建一个提取器类,以从通知附加信息中重新创建所有不同类型的通知。所以,即使有延迟,上帝保佑你! recoverBuilder.. 该死的 android 文档...
  • 不幸的是,经过一些研究和测试,我发现这种方法不是 100% 可靠的。在 MIUI 10 手机(例如小米)上,所有通知都已损坏(同一行多行文本,或带有覆盖所有通知区域的回复按钮的通知)
【解决方案2】:

经过调查,无法检索通知的全部内容(即检索通知 Remoteviews),除非发件人使用自定义布局调用 setCustomContentView() 和/或 setCustomBigContentView()。

也就是说,这里唯一的解决方案是使用与原始通知相同的信息重新创建一个 Remoteview(或两个,如果您想同时拥有紧凑版和扩展版)。为此,从 Bundle 通知 extras 中提取的信息将用于填充您应该创建的 XML 通知布局,类似于以下内容:

Android N notification design

此外,您必须检查 extras Bundle 是否包含 Notification.EXTRA_TEMPLATE 键,如果是,请检查其样式。 XML 布局应复制不同类型的边框(MediaStyle、InboxStyle、BigPictureStyle)并相应地填充所有字段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多