Micha F.
Micha F.

Reputation: 634

NotificationCompat.InboxStyle: How many lines can I add at most?

I use NotificationCompat.InboxStyle to show a notification.

I was not able to find out how many lines I can add at most with NotificationCompat#addLine() so that all inbox-messages are still visible in the (expanded) notification.

I found this in the documentation of NotificationCompat.InboxStyle:

Helper class for generating large-format notifications that include a list of (up to 5) strings.

According to this, it would be five lines max.

But:
(1) In NotificationCompat.java I found this:

private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024;

...

ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>();

...

/**
 * Append a line to the digest section of the Inbox notification.
 */
public InboxStyle addLine(CharSequence cs) {
    mTexts.add(Builder.limitCharSequenceLength(cs));
    return this;
}

...

protected static CharSequence limitCharSequenceLength(CharSequence cs) {
    if (cs == null) return cs;
    if (cs.length() > MAX_CHARSEQUENCE_LENGTH) {
        cs = cs.subSequence(0, MAX_CHARSEQUENCE_LENGTH);
    }
    return cs;
}

This shows that the lines are not limited when creating the InboxStyle.

(2) I found out, by trying, that I could add 7 lines that would show in the expanded view of the notification on my Android phone. When I added 8 lines, it would show "..." as 7th inbox-message.

So now my question(s):
Is the limit of inbox-message-lines always 7 or is the limit device-specific, like depending on the screen-size of the device?

If it is device-specific, which would be the number of lines I could be sure that they are shown on all Android-versions (that support expanded notifications)?
Would that be the limit of five Strings mentioned in the documentation?

Or did I miss something? I just couldn't find out anything about it, and nobody seems to have had this problem before - I appreciate any help, thanks.

Upvotes: 1

Views: 3065

Answers (2)

Rushi M Thakker
Rushi M Thakker

Reputation: 679

Check the end line which is

private ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(5);

in Notification.java and explanation under it if you don't want to go through all this

Helper class for generating large-format notifications that include a list of (up to 5) strings.

If the platform does not provide large-format notifications, this method has no effect. The user will always see the normal notification view. This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:

Notification noti = new Notification.Builder()
     .setContentTitle(&quot;5 New mails from &quot; + sender.toString())
     .setContentText(subject)
     .setSmallIcon(R.drawable.new_mail)
     .setLargeIcon(aBitmap)
     .setStyle(new Notification.InboxStyle()
     .addLine(str1)
     .addLine(str2)
     .setContentTitle(&quot;&quot;)
     .setSummaryText(&quot;+3 more&quot;))
     .build();

This is what it says in its documentation.

You missed the whole picture of documentation. We display notifications with the following code.

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(1 /* ID of notification */, notificationBuilder.build());

Here is the code of notify in NotificationCompat.Builder.build()

    public Notification build() {
        return IMPL.build(this, getExtender());
    }

Here IMPL is a static interface that has the methods for implementations of notification methods

private static final NotificationCompatImpl IMPL;

interface NotificationCompatImpl {
    public Notification build(Builder b, BuilderExtender extender);
    public Bundle getExtras(Notification n);
    public int getActionCount(Notification n);
    public Action getAction(Notification n, int actionIndex);
    public Action[] getActionsFromParcelableArrayList(ArrayList<Parcelable> parcelables);
    public ArrayList<Parcelable> getParcelableArrayListForActions(Action[] actions);
    public String getCategory(Notification n);
    public boolean getLocalOnly(Notification n);
    public String getGroup(Notification n);
    public boolean isGroupSummary(Notification n);
    public String getSortKey(Notification n);
    Bundle getBundleForUnreadConversation(NotificationCompatBase.UnreadConversation uc);
    NotificationCompatBase.UnreadConversation getUnreadConversationFromBundle(
            Bundle b, NotificationCompatBase.UnreadConversation.Factory factory,
            RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory);
}

IMPL is defined using SDK_INT as

static {
        if (Build.VERSION.SDK_INT >= 21) {
            IMPL = new NotificationCompatImplApi21();
        } else if (Build.VERSION.SDK_INT >= 20) {
            IMPL = new NotificationCompatImplApi20();
        } else if (Build.VERSION.SDK_INT >= 19) {
            IMPL = new NotificationCompatImplKitKat();
        } else if (Build.VERSION.SDK_INT >= 16) {
            IMPL = new NotificationCompatImplJellybean();
        } else if (Build.VERSION.SDK_INT >= 14) {
            IMPL = new NotificationCompatImplIceCreamSandwich();
        } else if (Build.VERSION.SDK_INT >= 11) {
            IMPL = new NotificationCompatImplHoneycomb();
        } else if (Build.VERSION.SDK_INT >= 9) {
            IMPL = new NotificationCompatImplGingerbread();
        } else {
            IMPL = new NotificationCompatImplBase();
        }

Since I use JellyBean I checked into NotificationCompatImplJellybean.Build

static class NotificationCompatImplKitKat extends NotificationCompatImplJellybean {
        @Override
        public Notification build(Builder b, BuilderExtender extender) {
            NotificationCompatKitKat.Builder builder = new NotificationCompatKitKat.Builder(
                    b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
                    b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
                    b.mProgressMax, b.mProgress, b.mProgressIndeterminate, b.mShowWhen,
                    b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly,
                    b.mPeople, b.mExtras, b.mGroupKey, b.mGroupSummary, b.mSortKey);
            addActionsToBuilder(builder, b.mActions);
            addStyleToBuilderJellybean(builder, b.mStyle);
            return extender.build(b, builder);
        }

Here addStyleToBuilderJellybean() leads to

private static void addStyleToBuilderJellybean(NotificationBuilderWithBuilderAccessor builder,
            Style style) {
        if (style != null) {
            if (style instanceof BigTextStyle) {
                BigTextStyle bigTextStyle = (BigTextStyle) style;
                NotificationCompatJellybean.addBigTextStyle(builder,
                        bigTextStyle.mBigContentTitle,
                        bigTextStyle.mSummaryTextSet,
                        bigTextStyle.mSummaryText,
                        bigTextStyle.mBigText);
            } else if (style instanceof InboxStyle) {
                InboxStyle inboxStyle = (InboxStyle) style;
                NotificationCompatJellybean.addInboxStyle(builder,
                        inboxStyle.mBigContentTitle,
                        inboxStyle.mSummaryTextSet,
                        inboxStyle.mSummaryText,
                        inboxStyle.mTexts);
            } else if (style instanceof BigPictureStyle) {
                BigPictureStyle bigPictureStyle = (BigPictureStyle) style;
                NotificationCompatJellybean.addBigPictureStyle(builder,
                        bigPictureStyle.mBigContentTitle,
                        bigPictureStyle.mSummaryTextSet,
                        bigPictureStyle.mSummaryText,
                        bigPictureStyle.mPicture,
                        bigPictureStyle.mBigLargeIcon,
                        bigPictureStyle.mBigLargeIconSet);
            }
        }
    }

Here addInboxStyle goes to NotificationCompatJellyBean.java

public static void addInboxStyle(NotificationBuilderWithBuilderAccessor b,
            CharSequence bigContentTitle, boolean useSummary,
            CharSequence summaryText, ArrayList<CharSequence> texts) {
        Notification.InboxStyle style = new Notification.InboxStyle(b.getBuilder())
            .setBigContentTitle(bigContentTitle);
        if (useSummary) {
            style.setSummaryText(summaryText);
        }
        for (CharSequence text: texts) {
            style.addLine(text);
        }
    }

Here style.addLine(text) goes to Notification.java where it is declared as:

public InboxStyle addLine(CharSequence cs) {
            mTexts.add(safeCharSequence(cs));
            return this;
        }

Now see declaratoin of mTexts in Notification.java

private ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(5);

This shows that it limits the number of notification lines to 5. I know it is very complex to go through all this but in short at the end after going through all declarations it declares in Notification.java that this is limited to 5 lines only.

Classes used are: NotificationManagerCompat.java, NotificationCompatJellyBean.java and Notification.java

2) Regarding part 2 of your question. Even I don't understand why it shows 7 lines instead of 5 enter image description here This is the output of adding 8 lines. I am using Google Nexus S-4.1.1 device in emulator. Hence I think that this is device independent.

Upvotes: 3

Natan
Natan

Reputation: 301

The answer is simple and straightforward, the maximum is 5 as reported here: https://developer.android.com/reference/android/app/Notification.InboxStyle.html

Retrieved from the above link:

Helper class for generating large-format notifications that include a list of (up to 5) strings

Upvotes: -1

Related Questions