package com.plugin.gcm;
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import com.google.android.gcm.*;
/**
* @author awysocki
*/
public class PushPlugin extends CordovaPlugin {
public static final String TAG = "PushPlugin";
public static final String REGISTER = "register";
public static final String UNREGISTER = "unregister";
public static final String EXIT = "exit";
private static CordovaWebView gWebView;
private static String gECB;
private static String gSenderID;
private static Bundle gCachedExtras = null;
private static boolean gForeground = false;
/**
* Gets the application context from cordova's main activity.
* @return the application context
*/
private Context getApplicationContext() {
return this.cordova.getActivity().getApplicationContext();
}
@Override
public boolean execute(String action, JSONArray data, CallbackContext callbackContext) {
boolean result = false;
Log.v(TAG, "execute: action=" + action);
if (REGISTER.equals(action)) {
Log.v(TAG, "execute: data=" + data.toString());
try {
JSONObject jo = data.getJSONObject(0);
gWebView = this.webView;
Log.v(TAG, "execute: jo=" + jo.toString());
gECB = (String) jo.get("ecb");
gSenderID = (String) jo.get("senderID");
Log.v(TAG, "execute: ECB=" + gECB + " senderID=" + gSenderID);
GCMRegistrar.register(getApplicationContext(), gSenderID);
result = true;
callbackContext.success();
} catch (JSONException e) {
Log.e(TAG, "execute: Got JSON Exception " + e.getMessage());
result = false;
callbackContext.error(e.getMessage());
}
if ( gCachedExtras != null) {
Log.v(TAG, "sending cached extras");
sendExtras(gCachedExtras);
gCachedExtras = null;
}
} else if (UNREGISTER.equals(action)) {
GCMRegistrar.unregister(getApplicationContext());
Log.v(TAG, "UNREGISTER");
result = true;
callbackContext.success();
} else {
result = false;
Log.e(TAG, "Invalid action : " + action);
callbackContext.error("Invalid action : " + action);
}
return result;
}
/*
* Sends a json object to the client as parameter to a method which is defined in gECB.
*/
public static void sendJavascript(JSONObject _json) {
String _d = "javascript:" + gECB + "(" + _json.toString() + ")";
Log.v(TAG, "sendJavascript: " + _d);
if (gECB != null && gWebView != null) {
gWebView.sendJavascript(_d);
}
}
/*
* Sends the pushbundle extras to the client application.
* If the client application isn't currently active, it is cached for later processing.
*/
public static void sendExtras(Bundle extras)
{
if (extras != null) {
if (gECB != null && gWebView != null) {
sendJavascript(convertBundleToJson(extras));
} else {
Log.v(TAG, "sendExtras: caching extras to send at a later time.");
gCachedExtras = extras;
}
}
}
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
gForeground = true;
}
@Override
public void onPause(boolean multitasking) {
super.onPause(multitasking);
gForeground = false;
}
@Override
public void onResume(boolean multitasking) {
super.onResume(multitasking);
gForeground = true;
}
@Override
public void onDestroy() {
super.onDestroy();
gForeground = false;
gECB = null;
gWebView = null;
}
/*
* serializes a bundle to JSON.
*/
private static JSONObject convertBundleToJson(Bundle extras)
{
try
{
JSONObject json;
json = new JSONObject().put("event", "message");
JSONObject jsondata = new JSONObject();
Iterator<String> it = extras.keySet().iterator();
while (it.hasNext())
{
String key = it.next();
Object value = extras.get(key);
// System data from Android
if (key.equals("from") || key.equals("collapse_key"))
{
json.put(key, value);
}
else if (key.equals("foreground"))
{
json.put(key, extras.getBoolean("foreground"));
}
else if (key.equals("coldstart"))
{
json.put(key, extras.getBoolean("coldstart"));
}
else
{
// Maintain backwards compatibility
if (key.equals("message") || key.equals("msgcnt") || key.equals("soundname"))
{
json.put(key, value);
}
if ( value instanceof String ) {
// Try to figure out if the value is another JSON object
String strValue = (String)value;
if (strValue.startsWith("{")) {
try {
JSONObject json2 = new JSONObject(strValue);
jsondata.put(key, json2);
}
catch (Exception e) {
jsondata.put(key, value);
}
// Try to figure out if the value is another JSON array
}
else if (strValue.startsWith("["))
{
try
{
JSONArray json2 = new JSONArray(strValue);
jsondata.put(key, json2);
}
catch (Exception e)
{
jsondata.put(key, value);
}
}
else
{
jsondata.put(key, value);
}
}
}
} // while
json.put("payload", jsondata);
Log.v(TAG, "extrasToJSON: " + json.toString());
return json;
}
catch( JSONException e)
{
Log.e(TAG, "extrasToJSON: JSON exception");
}
return null;
}
public static boolean isInForeground()
{
return gForeground;
}
public static boolean isActive()
{
return gWebView != null;
}
}