Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Android Notification Channels: The Complicated ...
Search
Daniel Lew
September 05, 2017
Programming
1
380
Android Notification Channels: The Complicated Parts
Talk given to GDG Twin Cities.
Daniel Lew
September 05, 2017
Tweet
Share
More Decks by Daniel Lew
See All by Daniel Lew
How to Use Computers (Privately!)
dlew
0
40
Finding Meaningful, Mission-Driven Work
dlew
0
140
Things Maybe You Don't Know as a Newer Developer
dlew
1
110
Maintaining Software Correctness
dlew
4
1k
Grokking Coroutines (MinneBar)
dlew
5
630
ClimateChangeTech.pdf
dlew
0
130
What Tech Can Do About Climate Change
dlew
0
620
Grokking Coroutines
dlew
5
1.2k
Automated Tests Aren't Enough
dlew
0
510
Other Decks in Programming
See All in Programming
Swift Concurrency - 状態監視の罠
objectiveaudio
2
390
育てるアーキテクチャ:戦い抜くPythonマイクロサービスの設計と進化戦略
fujidomoe
1
150
defer f()とdefer fの挙動を 誤解していた話
kogamochiduki
2
160
CSS Linter の現在地 2025年のベストプラクティスを探る
ryo_manba
10
3.2k
私はどうやって技術力を上げたのか
yusukebe
43
17k
私達はmodernize packageに夢を見るか feat. go/analysis, go/ast / Go Conference 2025
kaorumuta
2
420
AccessorySetupKitで実現するシームレスなペアリング体験 / Seamless pairing with AccessorySetupKit
nekowen
0
210
麻雀点数計算問題生成タスクから学ぶ Single Agentの限界と Agentic Workflowの底力
po3rin
5
2k
メモリ不足との戦い〜大量データを扱うアプリでの実践例〜
kwzr
1
700
Repenser les filtres API Platform: une nouvelle syntaxe
vinceamstoutz
2
160
ネイティブ製ガントチャートUIを作って学ぶUICollectionViewLayoutの威力
jrsaruo
0
120
WebエンジニアがSwiftをブラウザで動かすプレイグラウンドを作ってみた
ohmori_yusuke
0
170
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.6k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
2.6k
The Invisible Side of Design
smashingmag
301
51k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.1k
BBQ
matthewcrist
89
9.8k
Into the Great Unknown - MozCon
thekraken
40
2.1k
Code Review Best Practice
trishagee
72
19k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Designing for Performance
lara
610
69k
[RailsConf 2023] Rails as a piece of cake
palkan
57
5.9k
Transcript
Android Notification Channels: The Complicated Parts Dan Lew
Goal • Inform users • …Without annoying them
Noises • Sound
Noises • Sound • Vibration
Noises • Sound • Vibration • Light
Noises v2 • Metadata • Priority • Categories • People
• Do not Disturb interruptions • Hiding on lock screen
Android Oreo • Notification badges on launcher • Channels
None
Channels give users control
User Control App Control Importance Sound Vibration Light Show on
lock screen Show badges on launcher Bypass "Do Not Disturb” Channel Name Channel Description
targetSdkVersion 26 == Channels
None
Measure Twice, Cut Once
How Many Channels?
Trello Channel Overview Important Minor Temporary Mentions New Cards Attachments
Due Soon Cards Boards Comments Memberships
Notification Groups
Importance IMPORTANCE_HIGH Make sound and pop on screen IMPORTANCE_DEFAULT Make
sound IMPORTANCE_LOW No sound IMPORTANCE_NONE No sound or visual interruption
Custom Noise • Sound • Vibration • Light
Bells and Whistles • Badges on launcher • Bypass “do
not disturb”
Playing Dirty • Can delete & recreate channels • Users
will know • Will annoy users
val channel = NotificationChannel("news", “News", NotificationManager.IMPORTANCE_DEFAULT) channel.description = "News and
weather" channel.setShowBadge(false) val manager = context.getSystemService(NotificationManager::class.java) manager.createNotificationChannel(channel)
val channel = NotificationChannel("news", “News", NotificationManager.IMPORTANCE_DEFAULT) channel.description = "News and
weather" channel.setShowBadge(false) val manager = context.getSystemService(NotificationManager::class.java) manager.createNotificationChannel(channel)
val notification = NotificationCompat.Builder(context, "news") .setThis() .setThat() .etc() .build()
Timing • Create channels at… • Startup • First notification
• Create all channels at once • Channel creation is idempotent
Inform users… ...WITHOUT annoying them
How to annoy users without really trying
Too Many Sounds
Too Many Rows
Notification Bundles 1-3 notifications 4+ notifications
Notification Bundles Pros Cons Easy Works across channels Many noises
Only on Nougat+
Notification Groups 1 notification 2+ notifications
Notification Groups
Notification Groups Pros Cons Few notifications Few noises Extra work
Notification Groups val summaryNotification = NotificationCompat.Builder(context, "news") ... .setGroupSummary(true) .setGroup("myGroup")
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY) .build() val childNotification = NotificationCompat.Builder(context, "news") ... .setGroupSummary(false) .setGroup("myGroup") .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY) .build()
Channels Break Groups • One group fails when channel disabled
• Group-per-channel creates too many rows • Group-per-channel creates too many noises
Channel Dilemma Bundling Groups Fewer rows Many noises Many rows
Fewer noises
Channel Solution • Channel should either… • Have a group
summary • Be IMPORTANCE_LOW or lower
Trello’s Setup Name Importance Summary Launcher Badge? Mentions HIGH Yes
Yes Due Soon DEFAULT Yes Yes Boards LOW No Yes Cards LOW No Yes Comments LOW No Yes Memberships LOW No Yes New Cards LOW No Yes Attachments MIN No No
Odds and Ends
Remove Notification Settings
Remove Notification Settings Intent
Listen to ACTION_LOCALE_CHANGED
Use setAlertOnlyOnce()
Summary • Embrace channels • Choose good defaults • Don’t
annoy users
Thank You! • danlew.net • @danlew42