I know that we can't set repeating alarms of short intervals in Android because it drains battery and has other such effects. Well, technically you can, but android will automatically push it up to a minute citing "suspiciously short duration".
So how exactly does an app like WhatsApp or Facebook constantly update our messages or newsfeed? I thought they fire an Alarm each second, but clearly that is impossible because the OS will push it up to a minute anyway. Using Handlers/Threads is off the question anyway because they don't fire when the app is closed, but WhatsApp updates your messages even when the app is closed.
So what exactly do these apps use if not AlarmManager to do the aforementioned task, and if they use AlarmManager, how do they set the short duration?
They have a service that uses push messaging. So basically they open a socket connection to a server and sleep until the server sends data to them. Its an interrupt mechanism, not a poll.
Not specific to any service like WhatsApp or Facebook, the idea behind this whole system works like this.
For Android in particular (or in general),
Your device registers with the Google Cloud Messaging (GCM) service
It allows GCM to create a HTTP persistent connection with your device
This connection is lightweight and persistent (stay alive for a long time)
With this, you will be able to consume these services, sending messages in this fashion.
Your Server ---> Google GCM Service ---> Target Device
When you send your messages, do not include the whole message itself. You should keep it lightweight by just sending simple messages to notify the targeted device that it has new information to be downloaded.
At your device application, you set up permissions and intent to listen for these push notifications. Whenever, there is new messages, you will make a request to your server to receive the corresponding messages.
Here's a guide to explain in depth: https://github.com/codepath/android_guides/wiki/Google-Cloud-Messaging
Cheers! Happy Programming!
Related
What I'm trying to ask is:
Whether these apps are relying on FCM/GCM (or any other type of) push notifications for syncing their data or are they using a socket connection in background through a service?
If they are relying on push notifications then why they don't have any loss in receiving notifications (in background) while I miss 10-15% of notifications in busy hours.
And if they are relying on a socket connection in background, then
ain't this eat battery like a dinosaur?
What I have found is that if I force stop Messenger and Facebook I still receive messages but somewhat late than usual.
Plus there is an option of 'Allow background activity' in Messenger, Facebook, Slack and Skype, which when I disable, I can't receive a notification at all.
Interesting this is that WhatsApp don't have this kinda option in its app info and If I just force stop WhatsApp it simply stops showing me message notifications.
Whether these apps are relying on FCM/GCM (or any other type of) push
notifications for syncing their data or are they using a socket
connection in background through a service?
They must be relying on FCM.
If they are relying on push notifications then why they don't have any
loss in receiving notifications (in background) while I miss 10-15% of
notifications in busy hours.
They must be using FCM high priority which are reliably delivered in doze mode.
And if they are relying on a socket connection in background, then
ain't this eat battery like a dinosaur?
They might not be running CPU intensive work.
Mobile applications like Whatsapp must be requesting permission to exempt them from Doze/battery saving and App standby mode. you can refer to my answer here for more details.
Adding on to Sagar answer.
1)Never show the notification from FCM notification payload unless required.
2)Once High priority FCM received you can do network operations for sometime and fetch data from server and then show up. If it fails whatsapp do puts ups with special msg.
https://www.quora.com/Why-do-I-get-You-may-have-new-messages-notification-on-WhatsApp
3)use foreground service/ cpu lock tied with app icon momentarily till the data is fetched ,later close it.
PS:No whatsapp do not request for Battery Optimization. they probably reply on FCM high-priority message.
Well I have no idea what EXACTLY are they doing in background (maybe no one has), but lets take a look at the concept.
In distributed systems and web applications, no one usually goes for push notification system in background for their services to talk to each other. While it is possible, but these alive services have better options to choose such as publisher/subscriber pattern and technologies that bring this service for us (ex: reddis, MQ, Nats.io), they are high available and with no single point of failure, and the data is still synced over all server.
Your second question starts with an if which might have a false result. But lets say they do. You should never compare your "client to server connections and logic" with "Server to server connections and logic". What I mean is maybe they use Reddis pub/sub service, it doesn't mean their client should use same system to connect to server. It has a big cost to keep those servers connections alive while supporting big numbers of messages to sync.
And about third question. No, socket connections don't always drain battery. It really depends on how you use them. You can check for sockets idle modes too.
Also, systems like firebase might be still be able to send notifications when an application is not running or not connected to server. Happened to me a lot of times in Telegram, when government of Iran has blocked it but I could still receive notifications. Its whole other story, I think you can find more about it with a little search.
PS: Please avoid asking too many questions at once. thanks.
For services which exchanging frequently messages like messenger, WhatsApp, and WeChat etc there are message brokers (Activemq Artemis, RabbitMQ, Kafka etc) which is running on the server and having active stomp connection with each client app. This broker forward the message to the respective client as it received, and if the client is not online then it hold the message in memory untill the client become online. For further details that how a message broker works visit the official website of my favorite Activemq Artemis docs.
I have a few apps which are dependent from server side. From there are getting they data.
The server side needed development anyhow. Server code hosting is done in our side. The client-server communication, structure is already up.
In this state we need to implement a push notification:
If there are new data on the server than it should be visible at user somehow.
The "standard", recommended way now is to use Google Cloud Messaging System.
I have a few concerns about it:
Requires client and server side coding and bind they technology in our code. And not this is the biggest:
Is changing relative often the technology: deprecation, and need to change our code. This is the biggest. Previous of this was something other and before that something other. In 4-5 years 3 changes is to much.
I am thinking to implement like this:
I will write a broadcast receiver listening when the user got internet connection.
On Internet connection it will check the server to see if it has something new or not.
If is does than it will show a notification and job is done. If the user clicks the notification it will start the app and download the playload.
I will use an alarm schedule, to check the server again after 1 or 15 min or 4 hours, whatever. There it will be no service running in background, just receivers!
The register - unregister functionality should be done in app.
Communications to server in plus:
registerMyDevice(IMEI)-or username+password
unregisterMyDevice(IMEI)
isSomethingNewData()
When the client comes to server it will send his IMEI anyhow to identify, so the server will know for who need to send push.
Anybody can take Google proposed solution and prove it is better in this case than our in-house solution?
The main problem with that solution is that you'll add one more background process that shortens the battery life. Imagine what would happen if many app developers choose to implement your solution. A user that installs several such applications will have their battery emptied quickly. With GCM, one connection is maintained with one server, and that connection serves all applications on the device.
I believe integration with GCM is simpler than developing a push solution by yourself. The API changes always come with improvements (original GCM allowed multiple senders while C2DM didn't; the new GCM gives you user notifications and device to cloud messaging), but even if you don't choose to work with them, the old APIs still work (even if they are deprecated).
One user manages mobile users via a website interface. By clicking on a button on that website I have to display the current position of the chosen mobile user. So what I need to do is send something to the mobile app to trigger sending the GPS position to my server. My website then starts polling the database to check every 10sec whether the GPS coordinates have arrived.
Questions:
Is it possible to use Push Notifications for this purpose? I already implemented it, so everything would be there.
Can I do that silently, so that the mobile user doesn't get notified? I have found something called Silent Push Notifications - is that what I'm searching for?
I have to do it on Android and iOS.
On Android it is definitelly possible. There is no default behavior (such as alerts/badges/sounds) to notify the user of the app that they got a notification. When the app gets a push notification, a broadcast receiver is created and its onReceive method executed. You can have whatever logic you need in that method, though if you require a logic that requires a long time to execute (such as server calls), you should start an intent service from the receiver and do you logic in the service (get the location of the device and send it to your server).
On iOS I believe it is possible since iOS7. Until iOS7, the application logic for handling the push notification would only be triggered after the user clicks on the notification/alert to open the app. iOS7 enable the app to do background processing as a result of the arriving push notification. I believe you should use the {"aps":{"content-available"=1}} payload in this case (which is used for background content downloads), since you don't want any payload that would be displayed to the user.
For android you have some ways to implement the push service:
GCM - http://developer.android.com/google/gcm/index.html:
MQTT - http://mqtt.org/
implement your own persistent connection.
All of them have their advantages. If you need a ack that the mobile client got the msg you should use MQTT. It is also faster than GCM because of less overhead and you don't have the GCM server in between. On the other hand GCM is easy to implement and you don't have to worry about the persistent TCP connection from your server.
Also the silent way is possible because you just trigger a service each time. so if you don't want a notification, the user don't get it.
I am not sure about iOS. For iOS6 it was not possible to implement your own service, which is necessary to "wake up" your app. I am not sure about about iOS7. So for iOS6 you definitely need to use Apples push server.
Is it possible to send push notifications to an android application without using Google server: C2DM?
So, I would like to have my own server which sends notifications directly to the app, but I'm not sure how are the notifications perceived by the device, because the device needs to receive notifications even if the app is not running and the notifications should appear in the notification center.
I think that the guys from www.airpush.com have managed to this, but I'm not sure how.
Can anyone help me with this please?
UPDATE:
Also I would like to know how to display the notifications in the notification center if I don't use C2DM? And if it is possible to configure the notification center to receive notifications from my server even if the user deletes the application developed by us, application which registered that device to receive notifications.
I want to send 3-4 notifications a day, but these notifications need to appear in the notification center and they should go only through our server. How can I configure the notification center within the app to make requests on my server for push notifications.
Thank You!
There is a solution from UrbanAirship called Helium push. According documentation Helium:
Works on Android 1.6 and higher
Does not require a Google Account
No default pushes per day limit
No default pushes per minute limit
Works on Amazon devices (e.g., Kindle Fire)
End to end Urban Airship support (i.e., API to to device)
Best throughput
The problem is that you need development app key for using this one.
Take a look at MQTT:
MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks.
It can be used (and was used in some applications) to implement custom server push solutions. One of the most well known applications using MQTT is Facebook Messanger.
You can easily find more information on MQTT in the Internet, e.g. in this SO question or in this blog post.
According to the FAQ on airpush.com, they're not using real push notifications but rather polling the server a few times per day. One reason I think this is a viable solution for you as well is that Android's C2DM apparently makes use of the Google Play Store, so it won't work on devices distributed outside of the Google eco-system. With over 5 Million Kindle Fires having sold already, that is worth thinking about.
From Airpush FAQ:
When executed once from the main activity of an Android™ application, the Airpush client utilizes Android™ OS's AlarmManager framework to schedule ongoing server polling events a few times per day. If an ad is polled from the server it is cached until optimal display time, which is algorithmically determined by the server.
Without using C2DM there's not option for a "real push notification". Because (afaik, correct me if I'm wrong) an android device registers at google (they can still deinstall malware from your phone via remote) and with this ip they are able to do a push notification. All other solutions could tend to be a "register at a server, keep the connection alive and wait for requests" or something and tend to be more battery-inefficient.
Parse has an excellent push notification service for Android, very easy to setup. More info here: Parse Android Notification Doc
If you want the user to only receive 3-4 messages per day and your messages are not bound to specific arrival times, you don't need pushing mechanisms.
Just create a service in your app that checks your own web service 5-10 times a day. If there is new data, make your app display it in the notification center.
If you don't want to have a service running all the time (like many messaging apps do), you can set up alarms (using the Android AlarmManager framework) that wake your app up regularily to check for new messages to display.
And if it is possible to configure the notification center to receive
notifications from my server even if the user deletes the application
developed by us, application which registered that device to receive
notifications.
That sounds like you want to write a virus or root kit ;-) You could use e-mails for your messages instead.
UPDATE 2013-12-30:
As just noted in my comment, rebuilding what GCM does is not a nice approach. It's enough when Google Services already load the device with this functionality. If your goal is just that Google does not see what messages you send to your users, you might aswell encrypt them. For Google not being able to actually read your messages, the client app should generate a key and send it to your server. All messages you send via GCM can then be encrypted using that key.
If you just want to circumvent Google's restriction on the amount of messages sent to users, you could pack multiple messages into one GCM notification and show them one after the other. But then again, we are back at some kind of polling solution as described before, with the exception that the user does not need to have internet access when you want to show the messages as they are cached on the device.
I have a requirement that my app, can receive events (e.g. messages) from server any time (even if app is not running). So do I need to create an infinitely running service to listen for these events?
This to me seems similar to Email apps in Smartphones, like whenever you receive a new email(event in my case), its able to show notifications and also able to update my list adapter whenever I receive an event.
But I dun know how will I implement this?
You should take a look at C2DM (push-messages):
http://code.google.com/intl/sv-SE/android/c2dm/index.html#intro
it allows a server to send messages to devices at any time.
From the link:
Here are the primary characteristics of Android Cloud to Device
Messaging (C2DM):
It allows third-party application servers to send lightweight messages to their Android applications. The messaging service is not
designed for sending a lot of user content via the messages. Rather,
it should be used to tell the application that there is new data on
the server, so that the application can fetch it.
[...]
An application on an Android device doesn’t need to be running to
receive messages. The system will wake up the application via Intent
broadcast when the the message arrives, as long as the application is
set up with the proper broadcast receiver and permissions.
[...]
Events from server are called "push notifications" and are implemented via "Cloud 2 device messaging" (C2DM). On the mobile side these messages are submitted as broadcast events (see BroadcastReceiver). For a complete example see some tutorials: Google, Vogella or here on Stackoverflow
I think you have to start a Service as soon as the device booted. There is a good tutorial here how to achieve this.