271

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.

wonea
  • 4,783
  • 17
  • 86
  • 139
Vinod
  • 3,209
  • 4
  • 20
  • 18
  • 4
    You can also watch Google I/O 2010 Presentation about Push Notification http://developer.android.com/videos/index.html#v=PLM4LajwDVc – vokilam Feb 02 '11 at 08:52
  • I think you can look at this post: http://stackoverflow.com/questions/17629942/ibm-worklight-how-to-setup-push-notification With Worklight you can receive push via different channels including GCM. – Neeraj Krishna Jan 15 '14 at 08:30
  • 1
    Google I/O 2010 presentation is available at http://www.youtube.com/watch?v=PLM4LajwDVc – elcuco Mar 16 '14 at 15:21
  • "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. – Deepscorn Apr 29 '15 at 11:39
  • have same issue http://stackoverflow.com/questions/35812304/pushnotification-not-working-properly – albert Mar 05 '16 at 09:30

20 Answers20

206

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).

0x6C38
  • 6,796
  • 4
  • 35
  • 47
BoD
  • 10,838
  • 6
  • 63
  • 59
  • it's in beta right now, but you can sign up in hopes of being activated. – brack Oct 06 '10 at 19:08
  • 3
    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 http://blog.boxedice.com/2010/10/07/android-push-notifications-tutorial/ – davidmytton Oct 07 '10 at 11:14
  • 6
    The problem is that you need a Google account for your users : which is, I think, a constraint. – kaffein Apr 17 '12 at 12:13
  • 33
    Note that Android Cloud to Device Messaging Framework has been deprecated. The new framework is called Google Cloud Messaging and can be found here: http://developer.android.com/guide/google/gcm/index.html – Ryan Berger Jul 09 '12 at 01:04
  • 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. – paiego Apr 13 '20 at 16:26
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.)

Community
  • 1
  • 1
dalelane
  • 2,746
  • 1
  • 24
  • 27
  • 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 Naren – Naren Nov 05 '09 at 06:14
  • 2
    It does hold a connection open. In a follow-up post (http://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 : http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006 pdf on that page, and Javadoc in the zip on that page) – dalelane Nov 05 '09 at 16:13
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.*

Kamran Ahmed
  • 7,661
  • 4
  • 30
  • 55
Lalit
  • 211
  • 2
  • 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. – Jan Feb 24 '14 at 08:42
  • 1
    @Jan: Google play app comes installed with device. User does not need to install. – Dexter Dec 20 '14 at 06:20
  • @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.) – Spencer D Dec 24 '15 at 18:54
  • So... Is MQTT the best option for Android devices which does not have Google Play installed? – Yeung Oct 04 '17 at 07:49
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

chiranjib
  • 5,288
  • 8
  • 53
  • 82
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());
     }
}
Community
  • 1
  • 1
swiftBoy
  • 35,607
  • 26
  • 136
  • 135
  • @Rohit did you checked the [**link**](http://rdcworld-android.blogspot.in/2013/11/android-push-notification-google-cloud.html) having complete tutorial. also please let me know what is missing I'll update the answer. – swiftBoy Dec 09 '13 at 07:29
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!

mtbkrdave
  • 2,900
  • 3
  • 23
  • 24
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.

peter
  • 269
  • 3
  • 3
  • 3
    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. – Crowe T. Robot Apr 23 '10 at 16:43
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.

Isaac Waller
  • 32,709
  • 29
  • 96
  • 107
  • 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. – haseman Sep 08 '09 at 22:36
  • No, actually, it won't, because idle TCP/IP connections take almost no power on the cell modem. – Isaac Waller Sep 08 '09 at 23:25
  • Actually, it will take a lot over time, so you are right. Sending keep-alives with long intervals helps a lot too. – Isaac Waller Sep 08 '09 at 23:26
  • What are "long intervals" in this regard? I know gmail push works like this but I don't know what timeout intervals they use. – tobsen Dec 18 '09 at 20:28
  • I found this image about battery performance Pull vs Push: https://labs.ericsson.com/files/battery.jpg I took it from the Ericsson Push API here: https://labs.ericsson.com/apis/mobile-java-push/documentation – Menda Jan 25 '11 at 09:33
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.

Community
  • 1
  • 1
Orr
  • 4,740
  • 3
  • 28
  • 31
6

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

Freek Nortier
  • 780
  • 1
  • 13
  • 27
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.

haseman
  • 11,213
  • 8
  • 41
  • 38
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.

n3utrino
  • 2,361
  • 3
  • 22
  • 32
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

j0k
  • 22,600
  • 28
  • 79
  • 90
Jacky
  • 21
  • 1
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

Milos Cuculovic
  • 19,631
  • 51
  • 159
  • 265
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

adimoh
  • 658
  • 2
  • 8
  • 20
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

Mohsen Afshin
  • 13,273
  • 10
  • 65
  • 90
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 ...

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.

Community
  • 1
  • 1
Sarel Botha
  • 12,419
  • 7
  • 54
  • 59
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

Fahed Hermoza
  • 343
  • 3
  • 11
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.

Arash Hatami
  • 5,297
  • 5
  • 39
  • 59