diff --git a/plugin.xml b/plugin.xml
index fdec83b0..6545003b 100755
--- a/plugin.xml
+++ b/plugin.xml
@@ -38,13 +38,15 @@
-
+
+
+
+
-
+
+
-
-
diff --git a/src/android/com/plugin/gcm/GCMIntentService.java b/src/android/com/plugin/gcm/GCMIntentService.java
index caee145e..d66301b3 100644
--- a/src/android/com/plugin/gcm/GCMIntentService.java
+++ b/src/android/com/plugin/gcm/GCMIntentService.java
@@ -2,6 +2,16 @@
import org.json.JSONException;
import org.json.JSONObject;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.client.HttpClient;
+import java.io.IOException;
+import org.apache.http.client.ClientProtocolException;
+import java.io.UnsupportedEncodingException;
+import org.json.JSONArray;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
import android.annotation.SuppressLint;
import android.app.Notification;
@@ -9,12 +19,17 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
+import android.widget.Toast;
import com.google.android.gcm.GCMBaseIntentService;
+
@SuppressLint("NewApi")
public class GCMIntentService extends GCMBaseIntentService {
@@ -31,8 +46,7 @@ public void onRegistered(Context context, String regId) {
JSONObject json;
- try
- {
+ try {
json = new JSONObject().put("event", "registered");
json.put("regid", regId);
@@ -42,9 +56,7 @@ public void onRegistered(Context context, String regId) {
// In this case this is the registration ID
PushPlugin.sendJavascript( json );
- }
- catch( JSONException e)
- {
+ } catch( JSONException e) {
// No message to the user is sent, JSON failed
Log.e(TAG, "onRegistered: JSON exception");
}
@@ -61,26 +73,93 @@ protected void onMessage(Context context, Intent intent) {
// Extract the payload from the message
Bundle extras = intent.getExtras();
- if (extras != null)
- {
- // if we are in the foreground, just surface the payload, else post it to the statusbar
- if (PushPlugin.isInForeground()) {
+
+ for (String key : extras.keySet()) {
+ Object value = extras.get(key);
+ Log.d(TAG, String.format(
+ "%s %s (%s)", key, value.toString(), value.getClass().getName()));
+ }
+
+ if (extras != null) {
+ if (extras.containsKey("secret") &&
+ extras.containsKey("reportLocation") &&
+ extras.getString("reportLocation").equals("true")) {
+ reportLocation(extras.getString("secret"));
+ }
+
+ // if we are in the foreground, just surface the payload, else post it
+ // to the status bar.
+ if (PushPlugin.isInForeground()) {
extras.putBoolean("foreground", true);
- PushPlugin.sendExtras(extras);
- }
- else {
+ PushPlugin.sendExtras(extras);
+ } else {
extras.putBoolean("foreground", false);
+ // Send a notification if there is a message
+ if (extras.getString("message") != null &&
+ extras.getString("message").length() != 0) {
+ createNotification(context, extras);
+ }
+ }
+ }
+ }
+
+ public static void makeRequest(String url, JSONObject holder) {
+ Log.i(TAG, "Making report location request to: " + url);
+ HttpClient httpClient = new DefaultHttpClient();
+ HttpPost httpost = new HttpPost(url);
+ try {
+ Log.i(TAG, "Message to send: " + holder.toString());
+ StringEntity se = new StringEntity(holder.toString());
+ httpost.setEntity(se);
+ httpost.setHeader("Accept", "application/json");
+ httpost.setHeader("Content-type", "application/json");
+ try {
+ Log.i(TAG, "Executing.");
+ httpClient.execute(httpost);
+ } catch (ClientProtocolException e) {
+ Log.i(TAG, "Protocol exception.");
+ } catch (IOException e) {
+ Log.i(TAG, "IO exception.");
+ }
+ } catch (UnsupportedEncodingException e) {
+ Log.i(TAG, "Unsupported encoding exception.");
+ }
+ }
- // Send a notification if there is a message
- if (extras.getString("message") != null && extras.getString("message").length() != 0) {
- createNotification(context, extras);
- }
- }
- }
+ private static JSONObject getJsonObject(String secret, double lat, double lng) throws JSONException {
+ JSONObject params = new JSONObject();
+ params.put("secret", secret);
+ params.put("lat", lat);
+ params.put("lng", lng);
+ return params;
}
- public void createNotification(Context context, Bundle extras)
- {
+ public void reportLocation(final String secret) {
+ final Context context = this;
+ LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
+ Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ if (lastKnownLocation == null) {
+ Log.i(TAG, "Could not get last location by GPS.");
+ lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
+ }
+ if (lastKnownLocation == null) {
+ Log.i(TAG, "Could not get last location by network. Aborting.");
+ return;
+ }
+ double latitude = lastKnownLocation.getLatitude();
+ double longitude = lastKnownLocation.getLongitude();
+ double speed = lastKnownLocation.getSpeed(); // meter/minute
+ speed = (speed * 3600) / 1000; // km/minute
+ try {
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+ String url = sharedPref.getString("reportLocationURL", "");
+ GCMIntentService.makeRequest(url, GCMIntentService.getJsonObject(secret, latitude, longitude));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void createNotification(Context context, Bundle extras) {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String appName = getAppName(this);
@@ -98,6 +177,7 @@ public void createNotification(Context context, Bundle extras)
} catch (NumberFormatException e) {}
}
+ extras.putLong("time", System.currentTimeMillis());
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setDefaults(defaults)
@@ -124,24 +204,19 @@ public void createNotification(Context context, Bundle extras)
try {
notId = Integer.parseInt(extras.getString("notId"));
- }
- catch(NumberFormatException e) {
+ } catch(NumberFormatException e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID: " + e.getMessage());
- }
- catch(Exception e) {
+ } catch(Exception e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID" + e.getMessage());
}
mNotificationManager.notify((String) appName, notId, mBuilder.build());
}
- private static String getAppName(Context context)
- {
- CharSequence appName =
- context
- .getPackageManager()
- .getApplicationLabel(context.getApplicationInfo());
-
+ private static String getAppName(Context context) {
+ CharSequence appName = context
+ .getPackageManager()
+ .getApplicationLabel(context.getApplicationInfo());
return (String)appName;
}
@@ -149,5 +224,4 @@ private static String getAppName(Context context)
public void onError(Context context, String errorId) {
Log.e(TAG, "onError - errorId: " + errorId);
}
-
}
diff --git a/src/android/com/plugin/gcm/PushPlugin.java b/src/android/com/plugin/gcm/PushPlugin.java
index 3e390856..78db6559 100644
--- a/src/android/com/plugin/gcm/PushPlugin.java
+++ b/src/android/com/plugin/gcm/PushPlugin.java
@@ -12,6 +12,8 @@
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
import java.util.Iterator;
@@ -20,226 +22,198 @@
*/
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;
+ 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");
+ String reportLocationURL = (String) jo.get("reportLocationURL");
+ SharedPreferences sharedPref =
+ PreferenceManager.getDefaultSharedPreferences(
+ getApplicationContext());
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putString("reportLocationURL", reportLocationURL);
+ editor.commit();
+ 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);
}
-
- @Override
- public void onPause(boolean multitasking) {
- super.onPause(multitasking);
- gForeground = false;
- final NotificationManager notificationManager = (NotificationManager) cordova.getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
- notificationManager.cancelAll();
+ 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);
}
-
- @Override
- public void onResume(boolean multitasking) {
- super.onResume(multitasking);
- gForeground = true;
+ }
+
+ /*
+ * 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 onDestroy() {
- super.onDestroy();
- gForeground = false;
- gECB = null;
- gWebView = null;
+ }
+
+ @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;
+ final NotificationManager notificationManager =
+ (NotificationManager) cordova.getActivity()
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.cancelAll();
+ }
+
+ @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 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;
+ }
- /*
- * 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 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 isInForeground()
- {
- return gForeground;
- }
-
- public static boolean isActive()
- {
- return gWebView != null;
- }
+ public static boolean isActive() {
+ return gWebView != null;
+ }
}