Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing location reporting on a specific type of GCM #554

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
10 changes: 6 additions & 4 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@
</config-file>

<config-file target="AndroidManifest.xml" parent="/manifest">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<permission android:name="$PACKAGE_NAME.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="$PACKAGE_NAME.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="$PACKAGE_NAME.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="$PACKAGE_NAME.permission.C2D_MESSAGE" />
</config-file>

<config-file target="AndroidManifest.xml" parent="/manifest/application">
Expand Down
138 changes: 106 additions & 32 deletions src/android/com/plugin/gcm/GCMIntentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,34 @@

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;
import android.app.NotificationManager;
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 {

Expand All @@ -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);

Expand All @@ -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");
}
Expand All @@ -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);

Expand All @@ -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)
Expand All @@ -124,30 +204,24 @@ 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;
}

@Override
public void onError(Context context, String errorId) {
Log.e(TAG, "onError - errorId: " + errorId);
}

}
Loading