6

I need to develop push notification system for android applications, not using google cloud messaging(security reasons). Here the server will notify all those devices that are currently logged on to a particular android application.

I know the question is pretty broad, but could anyone point me the possible solutions.

Thanks in advance.

Newbie
  • 129
  • 1
  • 3
  • 11
  • what sort of security reasons do you have that make you think twice if I may ask – tyczj Jul 01 '13 at 13:22
  • This a part of a banking application. And for the very same reason I was told that I could not use GCM. – Newbie Jul 01 '13 at 13:24
  • look at http://stackoverflow.com/questions/15297246/are-there-any-alternative-to-gcm-google-cloud-messaging-for-custom-android-bui – Seraphim's Jul 01 '13 at 13:30
  • How should I proceed if I need to write my own server for push notification (and not use any cloud service). Could anyone please guide me and give me breif overview of what frameworks to use to get started. – Newbie Jul 02 '13 at 01:36
  • Build your own messaging server. You can use websocket, XMPP or MQTT or others. the idea are similar like messaging app just the messaging should always use minimum payload and minimum connectivity, fast speed. – winsontan520 Sep 03 '14 at 09:20
  • Consider a paid product product that can be self-hosted on-premises and does not depend on GCM. Pushy (https://pushy.me) does just that and does not depend on Google Play Services. Full disclosure - I am the Founder & CEO at Pushy. – Elad Nava Aug 25 '18 at 09:53

2 Answers2

3

You can use MQTT for building a push notification service. (Note: applications like Facebook uses MQTT for push notifications).

So, to build a push notification service you need a MQTT broker running on the server (I recommend MQTT Mosquitto and a bachground service running on Android device.

Code for MQTT service (can be used both on the server and on the client sode):

/**
* MQTTManager class provide methods to connect, subscribe, publish, and listen to MQTT broker
*/
public class MQTTManager {

private final String TAG = "MQTT";
private final String BROKER_URL = "http://mqtt-dashboard.com/info/broker:1883"; //change it to your broker URL
private MqttClient mqttClient;
private String CLIENT_ID = "123"
private String topic = "ABC"
private int keepAliveInterval=60*5;
private MqttConnectOptions opt;

/**
 * Constructor
 * @throws MqttException
 */
protected MQTTManager() throws MqttException {
    opt=new MqttConnectOptions();
    opt.setKeepAliveInterval(keepAliveInterval);
    opt.setConnectionTimeout(10);
    mqttClient = new MqttClient(BROKER_URL, CLIENT_ID, new MemoryPersistence());
    mqttClient.setCallback(new MQTTCallback(BROKER_URL, CLIENT_ID, topic));
}

/**
 * Connects to the MQTT broker service on server side.
 */
public void connect(){
    try {
        mqttClient.connect(opt);
    } catch (MqttException e) {
        Log.e(TAG, "Error while connecting to mqtt broker: "+e.toString());
    }
}

/**
 * Subscribes the device to the topic provided via constructor
 */
public void subscribeDevice(){
    try {
        mqttClient.subscribe(this.topic);
    } catch (MqttException e) {
        Log.e(TAG, "Error while subscribing to mqtt broker: "+e.toString());
    }
}

/**
 * Publishes the message to the MQTT broker service.
 * @param String Message that needs to be published 
 */
public void publishToDevice(String message){
    try {
        MqttTopic mtopic=mqttClient.getTopic(this.topic);
        MqttMessage msg= new MqttMessage(message.getBytes());
        mtopic.publish(msg);
    } catch (MqttException e) {
        Log.e(TAG, "Error while publishing to mqtt broker: "+e.toString());
    }
}


/**
 * Inner class for mqtt callback
 */
public class MQTTCallback implements MqttCallback{

    final private String TAG = "MQTT";
    private String BROKER_URL;
    private String CLIENT_ID;                  
    private String TOPIC;
    private MqttClient mqttClient;

    public MQTTCallback(String BROKER_URL, String CLIENT_ID, String TOPIC) {
        this.BROKER_URL= BROKER_URL;
        this.CLIENT_ID = CLIENT_ID;
        this.TOPIC=TOPIC;
    }
    
    public void connectionLost(Throwable arg0) {
        connect();          
    }

    public void deliveryComplete(MqttDeliveryToken arg0) {
        if(arg0==null)
            System.out.print("Message delivered");          
    }

    public void messageArrived(MqttTopic arg0, MqttMessage arg1)
            throws Exception {
        // MESSAGE ARRIVES HERE!! argo-> device id & arg1 --> message
    }
}
}

To learn more, you can check the MQTT push notification service implemented in this project: SenSocial that I implemented.

If you don't have a broker running on your server, then you can try a publically available MQTT Mosquitto-based broker: MQTT BROKER

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
abhi
  • 1,412
  • 19
  • 25
0

I would recommend against not using GCM. Maintaining a persistent connection from the phone to the push server is expensive (in terms of battery usage but also actual money) and GCM does that for you for free. It is also not clear how do you plan to have a persistent socket listener in the background. It is likely that it will be killed by the framework at some point due to memory pressure. GCM runs in a privileged process which is way harder to kill.

Security wise I'd recommend encrypting whatever payload you have before sending it to the device, then decrypting in the phone itself. That would be way cheaper in terms of development costs and battery usage.

Miguel Garcia
  • 1,029
  • 5
  • 14
  • How would you implement push notifications on a private network though (like in a power plant with no outside internet connection) while maintaining the power usage benefits of GCM? – Jeremy Mar 18 '16 at 20:11