代码之家  ›  专栏  ›  技术社区  ›  target33

通知contentView和bigContentView在Android 7中为空

  •  3
  • target33  · 技术社区  · 8 年前

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

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

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

    /**
    * 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可以为null(实际上是)。 这些非常有用,因为您可以复制通知视图,其中还可以包含一些复杂的操作控件(例如媒体播放器通知,带有播放/暂停/停止控件):

    media player notification

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

    2 回复  |  直到 8 年前
        1
  •  3
  •   wgm    7 年前

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

    @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);
    }
    
        2
  •  2
  •   target33    8 年前

    这就是说,这里唯一的解决方案是使用与原始通知相同的信息重新创建Remoteview(如果希望同时具有压缩和扩展版本,则需要两个)。为此,需要从捆绑通知中提取信息 extras

    Android N notification design