SlideShare a Scribd company logo
Android Notifications
Or How I Learned to Stop Worrying and Love
NotificationCompat.Builder
Agenda:
1. How a Push Goes From A to B
2. Building a Notification
3. Troubleshooting Tips
How a push goes from A to B
● Firebase is the future
○ Acquired by Google in 2014
○ Has become Google’s mobile developer toolset
● Which should you use?
○ Existing GCM projects will still work
○ New projects must be created using Firebase
● What’s different?
○ Easier integration
○ All new features will be FCM only!
Google or Firebase Cloud Messaging?
Registration for Push
Slack API
Play Services
Backend
FirebaseInstanceIdService
Slack Android Client
Push flight plan
Slack
Message
Server
Slack Push
Server
Firebase Cloud
Messaging Server
Google Play Services
FirebaseMessagingService
SlackMessagingService
{
"to":
"e_a8VzsygpY:APA91bGGx4-LyXb1o8YJyO8Vdswf4Z1NGIZwh2hV06
Xx_bx1JCx4Lcd1W-Q8mG6wX8IYLods19BpVfsl23YHoHgqJpMbbPa70
xVZcNdzl0GMzzV4pzOrJe",
"priority": "high",
"data": { … }
}
What’s in a push (Part I: Google Bits)
{
"to":
"e_a8VzsygpY:APA91bGGx4-LyXb1o8YJyO8Vdswf4Z1NGIZwh2hV06
Xx_bx1JCx4Lcd1W-Q8mG6wX8IYLods19BpVfsl23YHoHgqJpMbbPa70
xVZcNdzl0GMzzV4pzOrJe",
"priority": "high",
"data": { … }
}
What’s in a push (Part I: Google Bits)
{
"to":
"e_a8VzsygpY:APA91bGGx4-LyXb1o8YJyO8Vdswf4Z1NGIZwh2hV06
Xx_bx1JCx4Lcd1W-Q8mG6wX8IYLods19BpVfsl23YHoHgqJpMbbPa70
xVZcNdzl0GMzzV4pzOrJe",
"priority": "high",
"data": { … }
}
What’s in a push (Part I: Google Bits)
Everything but the data section is stripped out when
the payload is passed to the application
"data": {
"sound": "b2.mp3",
"badge": 1,
"payload_version": "3",
"timestamp": "1469635289.000006",
"author_display_name": "Kodos Rigellian",
"author_avatar": "...",
"message": "hi",
"recent_messages": { … }
}
What’s in a push (Part II: Slack Bits)
"data": {
"sound": "b2.mp3",
"badge": 1,
"payload_version": "3",
"timestamp": "1469635289.000006",
"author_display_name": "Kodos Rigellian",
"author_avatar": "...",
"message": "hi",
"recent_messages": { … }
}
What’s in a push (Part II: Slack Bits)
Building a Notification
● NotificationCompat.Builder
○ Provides setters for each component of the notification
○ Can use anything exposed by it safely regardless of OS version
● NotificationManagerCompat
○ Posts built notifications using
notify(int id, Notification notification)
What to build and post with?
Basic Notification Example
builder.setContentTitle(title)
.setContentText(text)
.setColor(color)
.setSmallIcon(R.drawable.ic_notification_24dp)
.setLargeIcon(avatarBitmap)
.setWhen(dateTime.getMillis());
notificationManager.notify(id, builder.build());
Basic Notification Example
builder.setContentTitle(title)
.setContentText(text)
.setColor(color)
.setSmallIcon(R.drawable.ic_notification_24dp)
.setLargeIcon(avatarBitmap)
.setWhen(dateTime.getMillis());
notificationManager.notify(id, builder.build());
Basic Notification Example
builder.setContentTitle(title)
.setContentText(text)
.setColor(color)
.setSmallIcon(R.drawable.ic_notification_24dp)
.setLargeIcon(avatarBitmap)
.setWhen(dateTime.getMillis());
notificationManager.notify(id, builder.build());
Basic Notification Example
builder.setContentTitle(title)
.setContentText(text)
.setColor(color)
.setSmallIcon(R.drawable.ic_notification_24dp)
.setLargeIcon(avatarBitmap)
.setWhen(dateTime.getMillis());
notificationManager.notify(id, builder.build());
Basic Notification Example
builder.setContentTitle(title)
.setContentText(text)
.setColor(color)
.setSmallIcon(R.drawable.ic_notification_24dp)
.setLargeIcon(avatarBitmap)
.setWhen(dateTime.getMillis());
notificationManager.notify(id, builder.build());
Basic Notification Example
builder.setContentTitle(title)
.setContentText(text)
.setColor(color)
.setSmallIcon(R.drawable.ic_notification_24dp)
.setLargeIcon(avatarBitmap)
.setWhen(dateTime.getMillis());
notificationManager.notify(id, builder.build());
Basic Notification Example
builder.setContentTitle(title)
.setContentText(text)
.setColor(color)
.setSmallIcon(R.drawable.ic_notification_24dp)
.setLargeIcon(avatarBitmap)
.setWhen(dateTime.getMillis());
notificationManager.notify(id, builder.build());
BigTextStyle
builder.setContentTitle(title)
.setContentText(text)
…
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(text)
.setSummaryText(account.getTeamName()));
BigTextStyle
builder.setContentTitle(title)
.setContentText(text)
…
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(text)
.setSummaryText(account.getTeamName()));
BigTextStyle
builder.setContentTitle(title)
.setContentText(text)
…
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(text)
.setSummaryText(account.getTeamName()));
BigTextStyle
builder.setContentTitle(title)
.setContentText(text)
…
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(text)
.setSummaryText(account.getTeamName()));
BigTextStyle
builder.setContentTitle(title)
.setContentText(text)
…
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(text)
.setSummaryText(account.getTeamName()));
MessagingStyle
MessagingStyle messagingStyle = new MessagingStyle("Mike")
.setConversationTitle(contentTitle);
for (Message message : messagesForChannel) {
messagingStyle.addMessage(
message.getMessage(),
message.getTimestamp(),
message.getAuthor());
}
builder.setContentTitle(title)
.setContentText(text)
…
.setSubText(account.getTeamName())
.setStyle(messagingStyle);
MessagingStyle
MessagingStyle messagingStyle = new MessagingStyle("Mike")
.setConversationTitle(contentTitle);
for (Message message : messagesForChannel) {
messagingStyle.addMessage(
message.getMessage(),
message.getTimestamp(),
message.getAuthor());
}
builder.setContentTitle(title)
.setContentText(text)
…
.setSubText(account.getTeamName())
.setStyle(messagingStyle);
MessagingStyle
MessagingStyle messagingStyle = new MessagingStyle("Mike")
.setConversationTitle(contentTitle);
for (Message message : messagesForChannel) {
messagingStyle.addMessage(
message.getMessage(),
message.getTimestamp(),
message.getAuthor());
}
builder.setContentTitle(title)
.setContentText(text)
…
.setSubText(account.getTeamName())
.setStyle(messagingStyle);
MessagingStyle
MessagingStyle messagingStyle = new MessagingStyle("Mike")
.setConversationTitle(contentTitle);
for (Message message : messagesForChannel) {
messagingStyle.addMessage(
message.getMessage(),
message.getTimestamp(),
message.getAuthor());
}
builder.setContentTitle(title)
.setContentText(text)
…
.setSubText(account.getTeamName())
.setStyle(messagingStyle);
MessagingStyle
MessagingStyle messagingStyle = new MessagingStyle("Mike")
.setConversationTitle(contentTitle);
for (Message message : messagesForChannel) {
messagingStyle.addMessage(
message.getMessage(),
message.getTimestamp(),
message.getAuthor());
}
builder.setContentTitle(title)
.setContentText(text)
…
.setSubText(account.getTeamName())
.setStyle(messagingStyle);
MessagingStyle
MessagingStyle messagingStyle = new MessagingStyle("Mike")
.setConversationTitle(contentTitle);
for (Message message : messagesForChannel) {
messagingStyle.addMessage(
message.getMessage(),
message.getTimestamp(),
message.getAuthor());
}
builder.setContentTitle(title)
.setContentText(text)
…
.setSubText(account.getTeamName())
.setStyle(messagingStyle);
Still with us?
● A group consists of:
○ A set of one or more individual notifications
○ A single summary notification
■ Made by calling setGroupSummary(true)
● Groups are keyed by unique strings that you choose
● Android will NOT group your notifications until:
○ A second notification is posted to a specific group
○ A summary notification is posted
● You cannot post a summary in the same notify() call as a
notification!
Grouping Notifications
Grouping Notification Example
id=1000
groupKey=”MyGroup”
isGroupSummary=false
text=”My first message”
id=1999
groupKey=”MyGroup”
isGroupSummary=true
text=”My first message”
Pre-N Devices See The Most
Recently Posted Summary Only!
Wear + N and up Devices See These
as a Group
Grouping Notification Example
id=1000
groupKey=”MyGroup”
isGroupSummary=false
text=”My first message”
id=1001
groupKey=”MyGroup”
isGroupSummary=false
text=”My second message”
id=1999
groupKey=”MyGroup”
isGroupSummary=true
text=”2 new messages”
id=1999
groupKey=”MyGroup”
isGroupSummary=true
text=”My first message”
Grouping Visualized
Summary on KitKat Grouped on Nougat
● Build using stored notifications you’ve seen before
○ SharedPref/DB recommended as mentioned earlier
● Order can matter!
○ For best results, post the summary first, then the individual
notification
● Summaries don’t require sound, but set it anyways
○ Wear devices use the summary sound/vibrate data in some cases
Group Summaries Continued
● setAutoCancel(true) is almost always the right thing to do!
● Don’t forget to handle the user entering from the launcher icon or
recent app list!
Clearing Notifications
● NotificationManager’s clear(id) can do two things:
○ Clear an individual notification by id
Clearing Notifications
id=1000
groupKey=”MyGroup”
isGroupSummary=false
text=”My first message”
id=1001
groupKey=”MyGroup”
isGroupSummary=false
text=”My second message”
id=1999
groupKey=”MyGroup”
isGroupSummary=true
text=”2 new messages”
clear(1000)
clear(1001)
○ Clear an entire group by using the group summary’s notification id
● NotificationManager’s clear(id) can do two things:
○ Clear an individual notification by id
Clearing Notifications
id=1000
groupKey=”MyGroup”
isGroupSummary=false
text=”My first message”
id=1001
groupKey=”MyGroup”
isGroupSummary=false
text=”My second message”
id=1999
groupKey=”MyGroup”
isGroupSummary=true
text=”2 new messages”
clear(1999)
○ Clear an entire group by using the group summary’s notification id
● If you want to nuke the site from orbit...
○ clearAll()
Clearing Notifications
builder
.setContentIntent(userClickPendingIntent)
.setDeleteIntent(dismissPendingIntent)
Taking Action
Don’t forget to set these on both your individual notifications as well as the
group summary if present!
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
// Remote input instance to fetch data from the user
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_REPLY_TEXT)
.setLabel(replyLabelString)
.setChoices(/* string array */)
.build();
// Create the reply action and add the remote input
builder.addAction(
new NotificationCompat.Action.Builder(
replyDrawable, replyLabelString, pendingIntent)
.addRemoteInput(remoteInput)
.build());
------- Where you handle the pending intent ---------
RemoteInput.getResultsFromIntent(intent)
.getCharSequence(KEY_REPLY_TEXT);
Reply Action
Troubleshooting Tips
Tracking Pushes
● Each push your server sends is assigned a message id from Google
"message_id":"0:1479505763653918%3a63b8c3f9fd7ecd"
● Information to record
○ FCM message id
○ Internal unique id from your backend for this particular push
● Record this information on server and device side to determine if
○ Push was sent and received
○ Push was sent but not received
○ Push was sent and received more than once (Google error)
○ Push was sent twice and received twice (Local push server error)
Build a Silent Test Push System
● Come up with a data payload that indicates this is a test push
data {
isTest: true
id: <server generated id>
}
● Have client ack this push via an API to your backend
● Allows easy silent testing of pushes to confirm FCM link is working
We made it!
Q&A
Thanks!

More Related Content

Similar to Push Notifications Or: How I Learned to Stop Worrying and Love NotificationCompat.Builder

Local Notification Tutorial
Local Notification TutorialLocal Notification Tutorial
Local Notification Tutorial
Ketan Raval
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React Native
Damian Zbrożek
 
Deep Learning Edge
Deep Learning Edge Deep Learning Edge
Deep Learning Edge
Ganesan Narayanasamy
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
Mike Nakhimovich
 
Oopp Lab Work
Oopp Lab WorkOopp Lab Work
Oopp Lab Work
Heather Dionne
 
Google I/O 2016 replay - Android N Development
Google I/O 2016 replay - Android N DevelopmentGoogle I/O 2016 replay - Android N Development
Google I/O 2016 replay - Android N Development
Towhidul Haque Roni
 
8º Betabeers Granada: Android Wear por GDG Granada
8º Betabeers Granada: Android Wear por GDG Granada8º Betabeers Granada: Android Wear por GDG Granada
8º Betabeers Granada: Android Wear por GDG Granada
JM Robles
 
Easy path to machine learning (Spring 2021)
Easy path to machine learning (Spring 2021)Easy path to machine learning (Spring 2021)
Easy path to machine learning (Spring 2021)
wesley chun
 
Project proposal
Project proposalProject proposal
Project proposal
Maham Ejaz
 
Throughout the semester, we have been working on command line applic.pdf
Throughout the semester, we have been working on command line applic.pdfThroughout the semester, we have been working on command line applic.pdf
Throughout the semester, we have been working on command line applic.pdf
birajdar2
 
Top Tips for Android UIs - Getting the Magic on Tablets
Top Tips for Android UIs - Getting the Magic on TabletsTop Tips for Android UIs - Getting the Magic on Tablets
Top Tips for Android UIs - Getting the Magic on Tablets
Motorola Mobility - MOTODEV
 
Building a custom machine learning model on android
Building a custom machine learning model on androidBuilding a custom machine learning model on android
Building a custom machine learning model on android
Isabel Palomar
 
Introduction to Cloud Computing with Google Cloud
Introduction to Cloud Computing with Google CloudIntroduction to Cloud Computing with Google Cloud
Introduction to Cloud Computing with Google Cloud
wesley chun
 
426 lecture 4: AR Developer Tools
426 lecture 4: AR Developer Tools426 lecture 4: AR Developer Tools
426 lecture 4: AR Developer Tools
Mark Billinghurst
 
Creating a custom ML model for your application - DevFest Lima 2019
Creating a custom ML model for your application - DevFest Lima 2019Creating a custom ML model for your application - DevFest Lima 2019
Creating a custom ML model for your application - DevFest Lima 2019
Isabel Palomar
 
CodePool Liverpool 2013 - Microsoft Gadgeteer Presentation
CodePool Liverpool 2013 - Microsoft Gadgeteer PresentationCodePool Liverpool 2013 - Microsoft Gadgeteer Presentation
CodePool Liverpool 2013 - Microsoft Gadgeteer Presentation
Lee Stott
 
The Ring programming language version 1.6 book - Part 73 of 189
The Ring programming language version 1.6 book - Part 73 of 189The Ring programming language version 1.6 book - Part 73 of 189
The Ring programming language version 1.6 book - Part 73 of 189
Mahmoud Samir Fayed
 
How to create android push notifications with custom view
How to create android push notifications with custom viewHow to create android push notifications with custom view
How to create android push notifications with custom view
PushApps - Content Recommendation in Push Notifications
 
Cloud Messaging Flutter
Cloud Messaging FlutterCloud Messaging Flutter
Cloud Messaging Flutter
MuhammadAli408757
 
Mobile March Windows Azure Notification Hubs
Mobile March Windows Azure Notification HubsMobile March Windows Azure Notification Hubs
Mobile March Windows Azure Notification Hubs
Adam Grocholski
 

Similar to Push Notifications Or: How I Learned to Stop Worrying and Love NotificationCompat.Builder (20)

Local Notification Tutorial
Local Notification TutorialLocal Notification Tutorial
Local Notification Tutorial
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React Native
 
Deep Learning Edge
Deep Learning Edge Deep Learning Edge
Deep Learning Edge
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
 
Oopp Lab Work
Oopp Lab WorkOopp Lab Work
Oopp Lab Work
 
Google I/O 2016 replay - Android N Development
Google I/O 2016 replay - Android N DevelopmentGoogle I/O 2016 replay - Android N Development
Google I/O 2016 replay - Android N Development
 
8º Betabeers Granada: Android Wear por GDG Granada
8º Betabeers Granada: Android Wear por GDG Granada8º Betabeers Granada: Android Wear por GDG Granada
8º Betabeers Granada: Android Wear por GDG Granada
 
Easy path to machine learning (Spring 2021)
Easy path to machine learning (Spring 2021)Easy path to machine learning (Spring 2021)
Easy path to machine learning (Spring 2021)
 
Project proposal
Project proposalProject proposal
Project proposal
 
Throughout the semester, we have been working on command line applic.pdf
Throughout the semester, we have been working on command line applic.pdfThroughout the semester, we have been working on command line applic.pdf
Throughout the semester, we have been working on command line applic.pdf
 
Top Tips for Android UIs - Getting the Magic on Tablets
Top Tips for Android UIs - Getting the Magic on TabletsTop Tips for Android UIs - Getting the Magic on Tablets
Top Tips for Android UIs - Getting the Magic on Tablets
 
Building a custom machine learning model on android
Building a custom machine learning model on androidBuilding a custom machine learning model on android
Building a custom machine learning model on android
 
Introduction to Cloud Computing with Google Cloud
Introduction to Cloud Computing with Google CloudIntroduction to Cloud Computing with Google Cloud
Introduction to Cloud Computing with Google Cloud
 
426 lecture 4: AR Developer Tools
426 lecture 4: AR Developer Tools426 lecture 4: AR Developer Tools
426 lecture 4: AR Developer Tools
 
Creating a custom ML model for your application - DevFest Lima 2019
Creating a custom ML model for your application - DevFest Lima 2019Creating a custom ML model for your application - DevFest Lima 2019
Creating a custom ML model for your application - DevFest Lima 2019
 
CodePool Liverpool 2013 - Microsoft Gadgeteer Presentation
CodePool Liverpool 2013 - Microsoft Gadgeteer PresentationCodePool Liverpool 2013 - Microsoft Gadgeteer Presentation
CodePool Liverpool 2013 - Microsoft Gadgeteer Presentation
 
The Ring programming language version 1.6 book - Part 73 of 189
The Ring programming language version 1.6 book - Part 73 of 189The Ring programming language version 1.6 book - Part 73 of 189
The Ring programming language version 1.6 book - Part 73 of 189
 
How to create android push notifications with custom view
How to create android push notifications with custom viewHow to create android push notifications with custom view
How to create android push notifications with custom view
 
Cloud Messaging Flutter
Cloud Messaging FlutterCloud Messaging Flutter
Cloud Messaging Flutter
 
Mobile March Windows Azure Notification Hubs
Mobile March Windows Azure Notification HubsMobile March Windows Azure Notification Hubs
Mobile March Windows Azure Notification Hubs
 

More from DevFest DC

Reactive Programming in Akka
Reactive Programming in AkkaReactive Programming in Akka
Reactive Programming in Akka
DevFest DC
 
Containers, microservices and azure
Containers, microservices and azureContainers, microservices and azure
Containers, microservices and azure
DevFest DC
 
Programming Google apps with the G Suite APIs
Programming Google apps with the G Suite APIsProgramming Google apps with the G Suite APIs
Programming Google apps with the G Suite APIs
DevFest DC
 
Snowflakes in the Cloud Real world experience on a new approach for Big Data
Snowflakes in the Cloud Real world experience on a new approach for Big DataSnowflakes in the Cloud Real world experience on a new approach for Big Data
Snowflakes in the Cloud Real world experience on a new approach for Big Data
DevFest DC
 
Well, That Escalated Quickly: Anomaly Detection with Elastic Machine Learning
Well, That Escalated Quickly: Anomaly Detection with Elastic Machine LearningWell, That Escalated Quickly: Anomaly Detection with Elastic Machine Learning
Well, That Escalated Quickly: Anomaly Detection with Elastic Machine Learning
DevFest DC
 
Why uri storage and the modern android app
Why uri  storage and the modern android appWhy uri  storage and the modern android app
Why uri storage and the modern android app
DevFest DC
 
Myths of Angular 2: What Angular Really Is
Myths of Angular 2: What Angular Really IsMyths of Angular 2: What Angular Really Is
Myths of Angular 2: What Angular Really Is
DevFest DC
 
Android Things Robocar with TensorFlow for object recognition
Android Things Robocar with TensorFlow for object recognitionAndroid Things Robocar with TensorFlow for object recognition
Android Things Robocar with TensorFlow for object recognition
DevFest DC
 
Troubleshooting & debugging production microservices in Kubernetes with Googl...
Troubleshooting & debugging production microservices in Kubernetes with Googl...Troubleshooting & debugging production microservices in Kubernetes with Googl...
Troubleshooting & debugging production microservices in Kubernetes with Googl...
DevFest DC
 
Hack the Real World with ANDROID THINGS
Hack the Real World with ANDROID THINGSHack the Real World with ANDROID THINGS
Hack the Real World with ANDROID THINGS
DevFest DC
 
Using Cloud Vision To Watch The World’s News Imagery In Realtime: The GDELT P...
Using Cloud Vision To Watch The World’s News Imagery In Realtime: The GDELT P...Using Cloud Vision To Watch The World’s News Imagery In Realtime: The GDELT P...
Using Cloud Vision To Watch The World’s News Imagery In Realtime: The GDELT P...
DevFest DC
 
Teaching machines to see the process of designing (datasets) with ai
Teaching machines to see  the process of designing (datasets) with aiTeaching machines to see  the process of designing (datasets) with ai
Teaching machines to see the process of designing (datasets) with ai
DevFest DC
 

More from DevFest DC (12)

Reactive Programming in Akka
Reactive Programming in AkkaReactive Programming in Akka
Reactive Programming in Akka
 
Containers, microservices and azure
Containers, microservices and azureContainers, microservices and azure
Containers, microservices and azure
 
Programming Google apps with the G Suite APIs
Programming Google apps with the G Suite APIsProgramming Google apps with the G Suite APIs
Programming Google apps with the G Suite APIs
 
Snowflakes in the Cloud Real world experience on a new approach for Big Data
Snowflakes in the Cloud Real world experience on a new approach for Big DataSnowflakes in the Cloud Real world experience on a new approach for Big Data
Snowflakes in the Cloud Real world experience on a new approach for Big Data
 
Well, That Escalated Quickly: Anomaly Detection with Elastic Machine Learning
Well, That Escalated Quickly: Anomaly Detection with Elastic Machine LearningWell, That Escalated Quickly: Anomaly Detection with Elastic Machine Learning
Well, That Escalated Quickly: Anomaly Detection with Elastic Machine Learning
 
Why uri storage and the modern android app
Why uri  storage and the modern android appWhy uri  storage and the modern android app
Why uri storage and the modern android app
 
Myths of Angular 2: What Angular Really Is
Myths of Angular 2: What Angular Really IsMyths of Angular 2: What Angular Really Is
Myths of Angular 2: What Angular Really Is
 
Android Things Robocar with TensorFlow for object recognition
Android Things Robocar with TensorFlow for object recognitionAndroid Things Robocar with TensorFlow for object recognition
Android Things Robocar with TensorFlow for object recognition
 
Troubleshooting & debugging production microservices in Kubernetes with Googl...
Troubleshooting & debugging production microservices in Kubernetes with Googl...Troubleshooting & debugging production microservices in Kubernetes with Googl...
Troubleshooting & debugging production microservices in Kubernetes with Googl...
 
Hack the Real World with ANDROID THINGS
Hack the Real World with ANDROID THINGSHack the Real World with ANDROID THINGS
Hack the Real World with ANDROID THINGS
 
Using Cloud Vision To Watch The World’s News Imagery In Realtime: The GDELT P...
Using Cloud Vision To Watch The World’s News Imagery In Realtime: The GDELT P...Using Cloud Vision To Watch The World’s News Imagery In Realtime: The GDELT P...
Using Cloud Vision To Watch The World’s News Imagery In Realtime: The GDELT P...
 
Teaching machines to see the process of designing (datasets) with ai
Teaching machines to see  the process of designing (datasets) with aiTeaching machines to see  the process of designing (datasets) with ai
Teaching machines to see the process of designing (datasets) with ai
 

Recently uploaded

Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
davidjhones387
 
Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?
Paul Walk
 
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
ysasp1
 
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
bseovas
 
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
uehowe
 
Azure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdfAzure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdf
AanSulistiyo
 
Gen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needsGen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needs
Laura Szabó
 
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
uehowe
 
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
cuobya
 
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
cuobya
 
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalmanuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
wolfsoftcompanyco
 
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
bseovas
 
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
zyfovom
 
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdfMeet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Florence Consulting
 
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
cuobya
 
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
uehowe
 
Explore-Insanony: Watch Instagram Stories Secretly
Explore-Insanony: Watch Instagram Stories SecretlyExplore-Insanony: Watch Instagram Stories Secretly
Explore-Insanony: Watch Instagram Stories Secretly
Trending Blogers
 
7 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 20247 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 2024
Danica Gill
 
Search Result Showing My Post is Now Buried
Search Result Showing My Post is Now BuriedSearch Result Showing My Post is Now Buried
Search Result Showing My Post is Now Buried
Trish Parr
 
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
xjq03c34
 

Recently uploaded (20)

Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
 
Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?
 
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
 
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
 
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
 
Azure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdfAzure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdf
 
Gen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needsGen Z and the marketplaces - let's translate their needs
Gen Z and the marketplaces - let's translate their needs
 
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
 
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
 
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
可查真实(Monash毕业证)西澳大学毕业证成绩单退学买
 
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalmanuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
manuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
 
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
 
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
 
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdfMeet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
 
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
 
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
留学挂科(UofM毕业证)明尼苏达大学毕业证成绩单复刻办理
 
Explore-Insanony: Watch Instagram Stories Secretly
Explore-Insanony: Watch Instagram Stories SecretlyExplore-Insanony: Watch Instagram Stories Secretly
Explore-Insanony: Watch Instagram Stories Secretly
 
7 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 20247 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 2024
 
Search Result Showing My Post is Now Buried
Search Result Showing My Post is Now BuriedSearch Result Showing My Post is Now Buried
Search Result Showing My Post is Now Buried
 
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
 

Push Notifications Or: How I Learned to Stop Worrying and Love NotificationCompat.Builder