Click here to Skip to main content
11,578,524 members (60,089 online)
Click here to Skip to main content

Push to Single Android Device

, 3 Jun 2014 CPOL 5.3K 107 8
Rate this:
Please Sign up or sign in to vote.
Alternative Push Notifications (without GCM) targeting a single device

Introduction

This is a rather atypical way to achieve reliable push notifications, on a single Android device. It does not use Google Cloud Messaging for delivery, thus eliminates the problem of delayed or even lost notifications many of us struggle with when using GCM. On the other hand, unlike GCM, this solution is limited to a single receiving device at once.

The solution uses PAW web server for Android (open source) and a specific BeanShell script to transform web requests into native Android broadcast messages. This makes it ideal if you'd like to target a specific device with your push notifications. You just need a simple BroadcastReceiver in your app and you're ready to go!

To make the target Android device visible even behind a strictly configured firewall, the solution uses PageKite for Android (open source) which works just fine on 3G/Wifi networks, with carriers which assign private IP addresses to your 3G-connected device (e.g. 10.0.0.3).

What It Is

An alternative way of sending push notifications to an Android device, useful for those who experience badly delayed and many times even completely lost push notifications through Google's own solution (GCM). With this alternative method, push notifications always arrive instantly, as soon as the web server processes a web request. This solution also supports devices older than Android 2.2 (no GCM used) and does not require rooting. It can be also a great resource for an example usage of BeanShell scripting.

Zero hacking is needed to get started.

What It Is Not

Not a full replacement for all features of GCM: mainly because this solution always targets a single device at a time.

If you don't mind setting up a server for Deacon, doing some hacks using MQTT or even utilizing a commercial solution instead, then this article is probably not for you.

Architecture

Any device capable of making web requests can be a push notification sender and any Android device can be a receiver of those push notifications.

Sender makes a web request like this:
(a quick free registration on PageKite is required when not running your own PageKite service)

http://YourName.pagekite.me/pushNotif.xhtml?message=TurnOnCommand 

PageKite will redirect the web request to your Android device, even if it is on 3G or trapped behind NAT or strict firewalls. The PAW web server running on your device will process the request by executing the following BeanShell script:

import android.os.*;
import android.content.*;

service = server.props.get("serviceContext");
messageText = parameters.get("message");

intent = new Intent("com.KurAttila.pushToSingleAndroidDevice.WebServerMessage");
intent.putExtra("message", messageText);
service.sendBroadcast(intent);  

This BeanShell script sends out a native Android OS broadcast - effectively transforming web requests into native Android OS broadcasts. Your Android application running on the same device can then capture that broadcast through its own, simple BroadcastReceiver.

Using the Code

Steps to quickly get you up and running:

  • Install PAW Server and PageKite (free registration required) on receiver device
  • Copy the provided pushNotif.xhtml (contains BeanShell script) into /sdcard/paw/html
  • Incorporate a simple BroadcastReceiver into your app code - like the following:
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String newMessage = intent.getExtras().getString("message");
        MainActivity.this.onNotification(newMessage);

        setResultCode(Activity.RESULT_OK);
    }
} 

Running the attached example will simply list all the notifications received:

Points of Interest

The basic idea emerged when designing a homebrew solution for gardening. I wanted a way to turn my old Android phone into an irrigation controller in my garden. The initial solution consisted of a polling based architecture: the Android device attached to the watering pump would retrieve some web storage content once every minute, to detect if there are any new "commands" to process (e.g. turn on watering, take a photo of the garden and upload it somewhere, turn off watering). It worked just fine, but the delays bothered me. So I gave a try to Google's push notifications, which happened to work OK - sometimes. And sometimes not. I've experienced heavily delayed and even never arriving notifications.

Instead of having those non-reliable push notifications, I've also tried to get away simply with much more frequent polling of commands ("messages"). This way, I could indeed detect new commands almost instantly, but given a very simple web response of around 250 bytes, being received every 3 seconds (to make it "instant"), the device would get a daily traffic of around 7 MB. Even if there's no new command, actually. This was just too much for that 3G data plan the device actually had, so I knew I needed another solution. Data usage of this web server-based solution indeed turned out to be much less.

In the meantime, I've also discovered several "push notification fixer" apps, which could indeed improve our unpleasant development experience with GCM. Unfortunately, they require Android 2.2+ and a rooted device - not a good match for my specific case.

History

  • 2014-May-29: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Attila Kúr
Software Developer (Senior)
Slovakia Slovakia
No Biography provided

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 4 Pin
xfzheng8-Jun-14 15:42
memberxfzheng8-Jun-14 15:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150603.1 | Last Updated 3 Jun 2014
Article Copyright 2014 by Attila Kúr
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid