Push Notifications in Android Platform
Asked Answered
F

20

272

I am looking to write an app that receives pushed alerts from a server. I found a couple of methods to do this.

  1. SMS - Intercept the incoming SMS and initiate a pull from the server
  2. Poll the server periodically

Each has its own limitations. SMS- no guarantee on arrival time. Poll may drain the battery.

Do you have a better suggestion please? Thanks very much.

Flam answered 4/9, 2009 at 11:25 Comment(5)
You can also watch Google I/O 2010 Presentation about Push Notification developer.android.com/videos/index.html#v=PLM4LajwDVcPersecution
I think you can look at this post: #17630442 With Worklight you can receive push via different channels including GCM.Yttria
Google I/O 2010 presentation is available at youtube.com/watch?v=PLM4LajwDVcKirkman
"Poll may drain the battery." You can shedule poll with AlarmManager, so the battery is not heavy-drained. It's simple and free (no need to pay, like with GCM) solution.Disconsolate
have same issue #35812804Gainor
A
207

Google's official answer is the Android Cloud to Device Messaging Framework (deprecated) Google Cloud Messaging(deprecated) Firebase Cloud Messaging

It will work on Android >= 2.2 (on phones that have the Play Store).

Axiom answered 2/8, 2010 at 7:54 Comment(5)
it's in beta right now, but you can sign up in hopes of being activated.Abagail
You can generally get activated very quickly, and it is being used for things like GMail so is know to work in production. Unfortunately their sample code for communicating with the server side aspect of C2DM is lacking. I've written up a tutorial for that aspect here blog.boxedice.com/2010/10/07/…Evolute
The problem is that you need a Google account for your users : which is, I think, a constraint.Katabatic
Note that Android Cloud to Device Messaging Framework has been deprecated. The new framework is called Google Cloud Messaging and can be found here: developer.android.com/guide/google/gcm/index.htmlGoods
On April 10, 2018, Google deprecated GCM. The GCM server and client APIs were removed on May 29, 2019. Migrate GCM apps to Firebase Cloud Messaging (FCM), which inherits the reliable and scalable GCM infrastructure, plus many new features. See the migration guide to learn more.Teplitz
N
31

(cross-posting from an answer I gave to a similar question - Does Android support near real time push notification? )

I recently started playing with MQTT http://mqtt.org for Android as a way of doing this sort of thing (i.e. push notification that is not SMS but data driven, almost immediate message delivery, not polling, etc.)

I have a blog post with background information on this in case it's helpful

http://dalelane.co.uk/blog/?p=938

(Note: MQTT is an IBM technology, and I should point out that I work for IBM.)

Neckcloth answered 30/9, 2009 at 22:59 Comment(2)
Hi Dale, I read your blog post about MQTT and it definitely seems to fit the bill for almost instant notification on mobiles. But I haven't been able to find any information about how it actually does it. Does it keep a socket open at all times? How does it notify the server if its ip address has changed? Would appreciate it if you could shed some light on this. Cheers NarenPhilosophy
It does hold a connection open. In a follow-up post (dalelane.co.uk/blog/?p=1009) I did talk more about the implications of holding a connection open - did you see that? If the connection is broken, both the server and client can be notified. Then it's an application layer decision to decide how to respond (e.g. reconnect). There is more information in the docs referred to in the post (e.g. IA92 : www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006 pdf on that page, and Javadoc in the zip on that page)Neckcloth
N
20

My understanding/experience with Android push notification are:

  1. C2DM GCM - If your target android platform is 2.2+, then go for it. Just one catch, device users have to be always logged with a Google Account to get the messages.

  2. MQTT - Pub/Sub based approach, needs an active connection from device, may drain battery if not implemented sensibly.

  3. Deacon - May not be good in a long run due to limited community support.

Edit: Added on November 25, 2013

GCM - Google says...

For pre-3.0 devices, this requires users to set up their Google account on their mobile devices. A Google account is not a requirement on devices running Android 4.0.4 or higher.*

Nicol answered 4/3, 2012 at 10:38 Comment(4)
While a Google account is not required for 4.0.4 or higher it seems to require you to have the Google Play app installed. I wonder how you install that without having a Google account.Repartition
@Jan: Google play app comes installed with device. User does not need to install.Attempt
@Dexter, not all Android devices have Google Play installed by default. Most do have it installed by default, especially devices that are purchased from reputable phone vendors, but devices which just have the Android OS flashed to them may not always have Google Play. (For example, a lot of Android emulators, such as new Genymotion devices, do not have Google Play by default.)Signe
So... Is MQTT the best option for Android devices which does not have Google Play installed?Bivins
C
17

Android Cloud to Device Messaging Framework

Important: C2DM has been officially deprecated as of June 26, 2012. This means that C2DM has stopped accepting new users and quota requests. No new features will be added to C2DM. However, apps using C2DM will continue to work. Existing C2DM developers are encouraged to migrate to the new version of C2DM, called Google Cloud Messaging for Android (GCM). See the C2DM-to-GCM Migration document for more information. Developers must use GCM for new development.

Kindly check the following link:

http://developer.android.com/guide/google/gcm/index.html

Conners answered 4/7, 2012 at 8:39 Comment(0)
W
17

Here I have written few steps for How to Get RegID and Notification starting from scratch

  1. Create/Register App on Google Cloud
  2. Setup Cloud SDK with Development
  3. Configure project for GCM
  4. Get Device Registration ID
  5. Send Push Notifications
  6. Receive Push Notifications

You can find complete tutorial in below URL link

Getting Started with Android Push Notification : Latest Google Cloud Messaging (GCM) - step by step complete tutorial

enter image description here

Code snip to get Registration ID (Device Token for Push Notification).

Configure project for GCM


Update AndroidManifest file

For enable GCM in our project we need to add few permission in our manifest file Go to AndroidManifest.xml and add below code Add Permission

<uses-permission android:name="android.permission.INTERNET”/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-permission android:name="android.permission.VIBRATE" />

<uses-permission android:name=“.permission.RECEIVE" />
<uses-permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE" />
<permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

Add GCM Broadcast Receiver declaration

add GCM Broadcast Receiver declaration in your application tag

<application
        <receiver
            android:name=".GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" ]]>
            <intent-filter]]>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="" />
            </intent-filter]]>

        </receiver]]>
     
<application/>

Add GCM Servie declaration

<application
     <service android:name=".GcmIntentService" />
<application/>

Get Registration ID (Device Token for Push Notification)

Now Go to your Launch/Splash Activity

Add Constants and Class Variables

private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private final static String TAG = "LaunchActivity";
protected String SENDER_ID = "Your_sender_id";
private GoogleCloudMessaging gcm =null;
private String regid = null;
private Context context= null;

Update OnCreate and OnResume methods

@Override
protected void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_launch);
     context = getApplicationContext();
         if (checkPlayServices()) 
     {
            gcm = GoogleCloudMessaging.getInstance(this);
            regid = getRegistrationId(context);

            if (regid.isEmpty())
            {
                registerInBackground();
            }
            else
            {
            Log.d(TAG, "No valid Google Play Services APK found.");
            }
      }
 }

@Override protected void onResume()
{
       super.onResume();       checkPlayServices();
}


# Implement GCM Required methods (Add below methods in LaunchActivity)

private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.d(TAG, "This device is not supported - Google Play Services.");
                finish();
            }
            return false;
        }
        return true;
 }

private String getRegistrationId(Context context) 
{
   final SharedPreferences prefs = getGCMPreferences(context);
   String registrationId = prefs.getString(PROPERTY_REG_ID, "");
   if (registrationId.isEmpty()) {
       Log.d(TAG, "Registration ID not found.");
       return "";
   }
   int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
   int currentVersion = getAppVersion(context);
   if (registeredVersion != currentVersion) {
        Log.d(TAG, "App version changed.");
        return "";
    }
    return registrationId;
}

private SharedPreferences getGCMPreferences(Context context) 
{
    return getSharedPreferences(LaunchActivity.class.getSimpleName(),
                Context.MODE_PRIVATE);
}

private static int getAppVersion(Context context) 
{
     try 
     {
         PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
      } 
      catch (NameNotFoundException e) 
      {
            throw new RuntimeException("Could not get package name: " + e);
      }
}


private void registerInBackground() 
{     new AsyncTask() {
     Override
     protected Object doInBackground(Object... params) 
     {
          String msg = "";
          try 
          {
               if (gcm == null) 
               {
                        gcm = GoogleCloudMessaging.getInstance(context);
               }
               regid = gcm.register(SENDER_ID);               Log.d(TAG, "########################################");
               Log.d(TAG, "Current Device's Registration ID is: "+msg);     
          } 
          catch (IOException ex) 
          {
              msg = "Error :" + ex.getMessage();
          }
          return null;
     }     protected void onPostExecute(Object result) 
     { //to do here };
  }.execute(null, null, null);
}

Note : please store REGISTRATION_KEY, it is important for sending PN Message to GCM also keep in mine this will be unique for all device, by using this only GCM will send Push Notification.

Receive Push Notifications

Add GCM Broadcast Receiver Class

As we have already declared “GcmBroadcastReceiver.java” in our Manifest file, So lets create this class update receiver class code this way

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) 
    {        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
        Toast.makeText(context, “wow!! received new push notification", Toast.LENGTH_LONG).show();
    }
}

Add GCM Service Class

As we have already declared “GcmBroadcastReceiver.java” in our Manifest file, So lets create this class update receiver class code this way

public class GcmIntentService extends IntentService
{     public static final int NOTIFICATION_ID = 1;     private NotificationManager mNotificationManager;     private final static String TAG = "GcmIntentService";     public GcmIntentService() {
     super("GcmIntentService");     
     }     @Override
     protected void onHandleIntent(Intent intent) {
          Bundle extras = intent.getExtras();
          Log.d(TAG, "Notification Data Json :" + extras.getString("message"));

          GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
          String messageType = gcm.getMessageType(intent);          if (!extras.isEmpty()) {          if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
               .equals(messageType)) {
               sendNotification("Send error: " + extras.toString());
          } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
          .equals(messageType)) {
          sendNotification("Deleted messages on server: "
          + extras.toString());          // If it's a regular GCM message, do some work.
          } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
          .equals(messageType)) {
          // This loop represents the service doing some work.
          for (int i = 0; i < 5; i++) {
               Log.d(TAG," Working... " + (i + 1) + "/5 @ "
               + SystemClock.elapsedRealtime());               try {
                    Thread.sleep(5000);
               } catch (InterruptedException e) {
               }
             }
             Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
             sendNotification(extras.getString("message"));
           }
        }        // Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);
     }     // Put the message into a notification and post it.
     // This is just one simple example of what you might choose to do with
     // a GCM message.
     private void sendNotification(String msg) {          mNotificationManager = (NotificationManager) this
          .getSystemService(Context.NOTIFICATION_SERVICE);
          PendingIntent contentIntent = PendingIntent.getActivity(this, 0,          new Intent(this, LaunchActivity.class), 0);

          NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(          this)
          .setSmallIcon(R.drawable.icon)
          .setContentTitle("Ocutag Snap")
          .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
          .setContentText(msg)
          .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);

          mBuilder.setContentIntent(contentIntent);          mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
     }
}
Wandawander answered 29/11, 2013 at 6:33 Comment(1)
@Rohit did you checked the link having complete tutorial. also please let me know what is missing I'll update the answer.Wandawander
M
11

There is a new open-source effort to develop a Java library for push notifications on Android based on the Meteor web server. You can check it out at the Deacon Project Blog, where you'll find links to Meteor and the project's GitHub repository. We need developers, so please spread the word!

Mccusker answered 17/4, 2010 at 2:46 Comment(0)
E
9

You can use Xtify (http://developer.xtify.com) - they have a push notifications webservice that works with their SDK. it's free and so far, it's worked really well for me.

Eason answered 18/3, 2010 at 22:47 Comment(1)
I got a response from their VP saying that there's no plans on ever charging for the push service. It's quite an amazing SDK.Rigsdaler
B
8

or....

3) Keep a connection to the server, send keep-alives every few minutes, and the server can push messages instantly. This is how Gmail, Google Talk, etc. works.

Blackmon answered 4/9, 2009 at 22:20 Comment(5)
I think this will, sadly, produce a hefty amount of battery drain. IF you take this route, make sure to limit the amount of time you do this.Extravascular
No, actually, it won't, because idle TCP/IP connections take almost no power on the cell modem.Blackmon
Actually, it will take a lot over time, so you are right. Sending keep-alives with long intervals helps a lot too.Blackmon
What are "long intervals" in this regard? I know gmail push works like this but I don't know what timeout intervals they use.Wreckage
I found this image about battery performance Pull vs Push: labs.ericsson.com/files/battery.jpg I took it from the Ericsson Push API here: labs.ericsson.com/apis/mobile-java-push/documentationHawkins
S
6

I recommend using GCM - Google Cloud Messaging for Android It's free, and for simple uses it's should be very easy.

However it requires to maintain a 3rd side server to send the notifications on your behalf. If you want to avoid that there are some very good industrial solutions for Android push notifications service:

  • Urban Airship - free up to 1M notifications per month, afterwards you are charged per 1000 notifications
  • PushApps - free for 1M notifications per month, and unlimited notifications for 19.99 per month
  • PushWoosh - free for 1M devices, premium plans are from 39 EURO

Diclaimer - I work in PushApps and also use their product in my applications for over a year now.

Strawflower answered 20/4, 2014 at 10:55 Comment(0)
H
6

As of 18/05/2016 Firebase is Google's unified platform for mobile developers including push notifications.

Helicoid answered 26/5, 2016 at 6:32 Comment(0)
E
4

I'm afraid you've found both possible methods. Google was, at least initially, going to implement a GChat api you could use for a push/pull implementation. Sadly, that library was cut by Android 1.0.

Extravascular answered 4/9, 2009 at 16:39 Comment(1)
They've promised to bring it back once the security problems get worked out... if that ever happens.Barong
K
3

I dont know if this is still useful. I achieved something like this with a java library at http://www.pushlets.com/

Althoug doing it in a service won't prevent android from shutting it down an killing the listener thread.

Kindly answered 20/10, 2009 at 20:48 Comment(0)
H
2

C2DM: your app-users must have the gmail account.

MQTT: when your connection reached to 1024, it will stop work because of it used "select model " of linux.

There is a free push service and api for android, you can try it: http://push-notification.org

Hamal answered 24/8, 2012 at 1:14 Comment(0)
H
2

Google C2DM is depreciated now, for that, you have o use the new service GCM (Google Cloud Messaging). For documantation, see http://developer.android.com/guide/google/gcm/gs.html

Hipbone answered 23/9, 2012 at 21:59 Comment(0)
Y
2

Free and easy method:

If your target user base is not large(less than a 1000) and you want a free service to start with, then Airbop is the best and most convenient.

Airbop Website It uses Google Cloud Messaging service through its API and is provides a good performance. i have used it for two of my projects and it was easy implementing it.

Services like and Urbanship are excellent but provide an entire deployment stack and not just the push notifications thing.

If only push service is your target, Airbop will work fine.

I haven't used Pushwoosh, but is also a great choice. It allows push to 1,000,000 devices for free

Yu answered 19/6, 2014 at 3:0 Comment(0)
N
1

I would suggest using both SMS and HTTP. If the user is not signed in send their phone an SMS to notify them there's a message waiting.

That's how this Ericsson Labs service works: https://labs.ericsson.com/apis/mobile-java-push/

If you implement this yourself the tricky part is deleting the incoming SMS without the user seeing it. Or maybe it's ok if they see it in your case.

Looks like this works: Deleting SMS Using BroadCastReceiver - Android

Yes, writing code like this can be dangerous and you can potentially ruin someone's life because your application deleted an SMS it shouldn't have.

Neoterize answered 11/1, 2011 at 22:29 Comment(2)
lol: "Yes, writing code like this can be dangerous and you can potentially ruin someone's life because your application deleted an SMS it shouldn't have." upvote for that. lol.Yasminyasmine
The link to Mobile Java Push is dead, and the service itself seems to be deprecated.Equidistant
P
1

You can use Google Cloud Messaging or GCM, it's free and easy to use. Also you can use third party push servers like PushWoosh which gives you more flexibility

Pleasance answered 10/10, 2012 at 17:5 Comment(0)
L
1

There's a lot a third party servers like Urban Airship, Xtify, Mainline, ... whiches allow send not only on Android, but also on iOs, Windows Phone ...

Lourielouse answered 11/2, 2013 at 14:10 Comment(0)
C
1

Firebase Cloud Messaging (FCM) is the new version of GCM. FCM is a cross-platform messaging solution that allows you to send messages securely and for free. Inherits GCM's central infrastructure to deliver messages reliably on Android, iOS, Web (javascript), Unity and C ++.

As of April 10, 2018, Google has disapproved of GCM. The GCM server and client APIs are deprecated and will be removed on April 11, 2019. Google recommends migrating GCM applications to Firebase Cloud Messaging (FCM), which inherits the reliable and scalable GCM infrastructure.

Resource

Cosignatory answered 22/10, 2018 at 21:24 Comment(0)
R
0

You can use Pusher

It's a hosted service that makes it super-easy to add real-time data and functionality to web and mobile applications.
Pusher offers libraries to integrate into all the main runtimes and frameworks.

PHP, Ruby, Python, Java, .NET, Go and Node on the server
JavaScript, Objective-C (iOS) and Java (Android) on the client.

Ruckus answered 14/12, 2017 at 17:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.