maxCharsPerSegment property
int
get
maxCharsPerSegment
The maximum number of characters that can fit in a single SMS segment given the current encoding.
This value changes depending on whether the message fits in one segment or requires multiple segments (concatenation). When concatenated, each segment includes a User Data Header (UDH) of 6 bytes (48 bits) that reduces the available space for message content.
Single-segment limits (no UDH):
| Encoding | Calculation | Max characters |
|---|---|---|
| GSM-7 | 1120 bits ÷ 7 bits | 160 |
| UCS-2 | 1120 bits ÷ 16 bits | 70 |
Multi-segment limits (with UDH per segment):
| Encoding | Calculation | Max characters |
|---|---|---|
| GSM-7 | (1120 − 48) bits ÷ 7 bits | 153 |
| UCS-2 | (1120 − 48) bits ÷ 16 bits | 67 |
Why does the value change?
- Typing only GSM-7 characters (a-z, 0-9, basic punctuation) → the encoding is GSM-7 and you get 160 chars in one segment.
- As soon as a non-GSM character (emoji, Chinese, Arabic,
ç, etc.) is present → encoding switches to UCS-2 and the limit drops to 70. - Once the message exceeds one segment, the per-segment limit further reduces to 153 (GSM-7) or 67 (UCS-2) due to the UDH overhead.
Example:
final gsm = SegmentedMessage('Hello');
print(gsm.maxCharsPerSegment); // 160 (GSM-7, single segment)
final ucs2 = SegmentedMessage('Hello 😊');
print(ucs2.maxCharsPerSegment); // 70 (UCS-2, single segment)
final longGsm = SegmentedMessage('A' * 161);
print(longGsm.maxCharsPerSegment); // 153 (GSM-7, multi-segment)
Implementation
int get maxCharsPerSegment {
const int maxBitsInSegment = 1120; // 140 bytes × 8 bits
const int headerBits = 48; // 6 bytes × 8 bits (UDH for concatenated SMS)
if (segments.length <= 1 &&
!(segments.isNotEmpty && segments.first.hasUserDataHeader)) {
// Single segment — no UDH overhead
return maxBitsInSegment ~/ _bitsPerCharacter;
}
// Multi-segment — each segment includes a UDH
return (maxBitsInSegment - headerBits) ~/ _bitsPerCharacter;
}