diff --git a/plugin.xml b/plugin.xml
index 68a46ff3..a0df6414 100755
--- a/plugin.xml
+++ b/plugin.xml
@@ -41,6 +41,7 @@
+
@@ -56,6 +57,13 @@
+
+
+
+
@@ -63,7 +71,13 @@
+
+
+
+
+
+
diff --git a/src/android/com/plugin/android-support-v13.jar b/src/android/com/plugin/android-support-v13.jar
index cd47212b..3c1de8a2 100644
Binary files a/src/android/com/plugin/android-support-v13.jar and b/src/android/com/plugin/android-support-v13.jar differ
diff --git a/src/android/com/plugin/gcm/AlertDialogActivity.java b/src/android/com/plugin/gcm/AlertDialogActivity.java
new file mode 100644
index 00000000..3648c871
--- /dev/null
+++ b/src/android/com/plugin/gcm/AlertDialogActivity.java
@@ -0,0 +1,55 @@
+package com.plugin.gcm;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.util.Log;
+import android.view.Window;
+import android.view.WindowManager;
+import android.os.Vibrator;
+import android.content.Context;
+import android.app.KeyguardManager;
+import android.content.Context;
+
+public class AlertDialogActivity extends FragmentActivity {
+ private static final String TAG = "AlertDialogActivity";
+
+ private KeyguardManager _KeyguardManager;
+ private boolean _bScreenLocked = false;
+
+ public AlertDialogActivity() {
+ Log.d(TAG, "AlertDialogActivity#AlertDialogActivity(): check-1");
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Bundle extras = getIntent().getExtras();
+ AlertDialogFragment fragment = new AlertDialogFragment(extras);
+ fragment.show(getSupportFragmentManager(), "alert_dialog");
+ Log.d(TAG, "AlertDialogActivity#onCreate(): check-1");
+
+ _KeyguardManager = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
+ _bScreenLocked = _KeyguardManager.inKeyguardRestrictedInputMode();
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ Log.d(TAG, "AlertDialogActivity#onAttachedToWindow(): check-1");
+ Window window = getWindow();
+ window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON // スクリーンをONにする
+ | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED // ロック画面の場合でも表示する
+ | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+ }
+ @Override
+ public void onStop() {
+ super.onStop();
+ _bScreenLocked = _KeyguardManager.inKeyguardRestrictedInputMode();
+ if(!_bScreenLocked)
+ {
+ final Vibrator vibrator =
+ (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
+ vibrator.cancel();
+ }
+ }
+}
diff --git a/src/android/com/plugin/gcm/AlertDialogFragment.java b/src/android/com/plugin/gcm/AlertDialogFragment.java
new file mode 100644
index 00000000..48b33172
--- /dev/null
+++ b/src/android/com/plugin/gcm/AlertDialogFragment.java
@@ -0,0 +1,112 @@
+package com.plugin.gcm;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.NotificationManager;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.support.v4.app.DialogFragment;
+import android.util.Log;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.graphics.drawable.BitmapDrawable;
+
+import com.google.gson.Gson;
+
+public class AlertDialogFragment extends DialogFragment {
+ private static final String TAG = "AlertDialogFragment";
+ private Bundle extras;
+ private AssetUtil assets;
+
+ public AlertDialogFragment(Bundle extras) {
+ this.extras = extras;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ final Bundle originalExtras = extras.getBundle("pushBundle");
+ final Context context = getActivity().getApplicationContext();
+ final NotificationManager notificationManager =
+ (NotificationManager)getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
+ final Vibrator vibrator =
+ (Vibrator)getActivity().getSystemService(Context.VIBRATOR_SERVICE);
+ String vibrateStrValue = originalExtras.getString("vibrate");
+ final long[] pattern = strValueToLongArray(vibrateStrValue);
+ Log.v(TAG, "onCreateDialog(): icon = "+ originalExtras.getString("icon"));
+ assets = AssetUtil.getInstance(context);
+ final Bitmap largeIcon = getLargeIcon(originalExtras.getString("icon"));
+
+ final int notId = Integer.parseInt(originalExtras.getString("notId"));
+ final String appName = GCMIntentService.getAppName(context);
+ Log.v(TAG, "onCreateDialog(): notId = "+ notId);
+ Dialog dialog = builder
+ .setTitle(originalExtras.getString("title"))
+ .setMessage(originalExtras.getString("text"))
+ .setIcon(new BitmapDrawable(largeIcon))
+ .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Intent intent = new Intent(context, PushHandlerActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ intent.putExtra("pushBundle", originalExtras);
+ startActivity(intent);
+ notificationManager.cancel(appName, notId);
+ vibrator.cancel();
+ }
+ })
+ .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ vibrator.cancel();
+ }
+ })
+ .create();
+ dialog.setCanceledOnTouchOutside(false);
+ vibrator.vibrate(pattern, -1);
+
+ return dialog;
+ }
+
+ private long[] strValueToLongArray(String vibrateStrValue) {
+ Gson gson = new Gson();
+
+ return gson.fromJson(vibrateStrValue, long[].class);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ getActivity().finish();
+ }
+
+ public int getSmallIcon(String smallIcon) {
+ int resId = assets.getResIdForDrawable(smallIcon);
+
+ if (resId == 0) {
+ resId = android.R.drawable.ic_menu_mylocation;
+ }
+
+ return resId;
+ }
+
+ public Bitmap getLargeIcon(String icon) {
+ Bitmap bmp;
+
+ Log.d(TAG, "getLargeIcon(): icon = "+ icon);
+
+ try{
+ Uri uri = assets.parse(icon);
+ Log.d(TAG, "getLargeIcon(): uri = "+ uri);
+ bmp = assets.getIconFromUri(uri);
+ } catch (Exception e){
+ bmp = assets.getIconFromDrawable(icon);
+ }
+ Log.d(TAG, "getLargeIcon(): bmp = "+ bmp);
+
+ return bmp;
+ }
+}
diff --git a/src/android/com/plugin/gcm/AssetUtil.java b/src/android/com/plugin/gcm/AssetUtil.java
new file mode 100644
index 00000000..97689152
--- /dev/null
+++ b/src/android/com/plugin/gcm/AssetUtil.java
@@ -0,0 +1,442 @@
+/*
+Taken from https://github.com/katzer/cordova-plugin-local-notifications plugin
+ */
+
+/*
+ * Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
+ *
+ * @APPPLANT_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apache License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPPLANT_LICENSE_HEADER_END@
+ */
+
+package com.plugin.gcm;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.StrictMode;
+import android.util.Log;
+
+/**
+ * Util class to map unified asset URIs to native URIs. URIs like file:///
+ * map to absolute paths while file:// point relatively to the www folder
+ * within the asset resources. And res:// means a resource from the native
+ * res folder. Remote assets are accessible via http:// for example.
+ */
+class AssetUtil {
+
+ // Name of the storage folder
+ private static final String STORAGE_FOLDER = "/geofence_notifications";
+
+ // Placeholder URI for default sound
+ private static final String DEFAULT_SOUND = "res://platform_default";
+
+ // Ref to the context passed through the constructor to access the
+ // resources and app directory.
+ private final Context context;
+
+ /**
+ * Constructor
+ *
+ * @param context
+ * Application context
+ */
+ private AssetUtil(Context context) {
+ this.context = context;
+ }
+
+ /**
+ * Static method to retrieve class instance.
+ *
+ * @param context
+ * Application context
+ */
+ static AssetUtil getInstance(Context context) {
+ return new AssetUtil(context);
+ }
+
+ /**
+ * Parse path path to native URI.
+ *
+ * @param path
+ * Path to path file
+ */
+ Uri parseSound (String path) {
+
+ if (path == null || path.isEmpty())
+ return Uri.EMPTY;
+
+ if (path.equalsIgnoreCase(DEFAULT_SOUND)) {
+ return RingtoneManager.getDefaultUri(RingtoneManager
+ .TYPE_NOTIFICATION);
+ }
+
+ return parse(path);
+ }
+
+ /**
+ * The URI for a path.
+ *
+ * @param path
+ * The given path
+ */
+ Uri parse (String path) {
+
+ if (path.startsWith("res:")) {
+ return getUriForResourcePath(path);
+ } else if (path.startsWith("file:///")) {
+ return getUriFromPath(path);
+ } else if (path.startsWith("file://")) {
+ return getUriFromAsset(path);
+ } else if (path.startsWith("http")){
+ return getUriFromRemote(path);
+ }
+
+ return Uri.EMPTY;
+ }
+
+
+
+ /**
+ * URI for a file.
+ *
+ * @param path
+ * Absolute path like file:///...
+ *
+ * @return
+ * URI pointing to the given path
+ */
+ private Uri getUriFromPath(String path) {
+ String absPath = path.replaceFirst("file://", "");
+ File file = new File(absPath);
+
+ if (!file.exists()) {
+ Log.e("Asset", "File not found: " + file.getAbsolutePath());
+ return Uri.EMPTY;
+ }
+
+ return Uri.fromFile(file);
+ }
+
+ /**
+ * URI for an asset.
+ *
+ * @param path
+ * Asset path like file://...
+ *
+ * @return
+ * URI pointing to the given path
+ */
+ private Uri getUriFromAsset(String path) {
+ File dir = context.getExternalCacheDir();
+
+ if (dir == null) {
+ Log.e("Asset", "Missing external cache dir");
+ return Uri.EMPTY;
+ }
+
+ String resPath = path.replaceFirst("file:/", "www");
+ String fileName = resPath.substring(resPath.lastIndexOf('/') + 1);
+ String storage = dir.toString() + STORAGE_FOLDER;
+ File file = new File(storage, fileName);
+
+ //noinspection ResultOfMethodCallIgnored
+ new File(storage).mkdir();
+
+ try {
+ AssetManager assets = context.getAssets();
+ FileOutputStream outStream = new FileOutputStream(file);
+ InputStream inputStream = assets.open(resPath);
+
+ copyFile(inputStream, outStream);
+
+ outStream.flush();
+ outStream.close();
+
+ return Uri.fromFile(file);
+
+ } catch (Exception e) {
+ Log.e("Asset", "File not found: assets/" + resPath);
+ e.printStackTrace();
+ }
+
+ return Uri.EMPTY;
+ }
+
+ /**
+ * The URI for a resource.
+ *
+ * @param path
+ * The given relative path
+ *
+ * @return
+ * URI pointing to the given path
+ */
+ private Uri getUriForResourcePath(String path) {
+ File dir = context.getExternalCacheDir();
+
+ if (dir == null) {
+ Log.e("Asset", "Missing external cache dir");
+ return Uri.EMPTY;
+ }
+
+ String resPath = path.replaceFirst("res://", "");
+
+ int resId = getResIdForDrawable(resPath);
+
+ if (resId == 0) {
+ Log.e("Asset", "File not found: " + resPath);
+ return Uri.EMPTY;
+ }
+
+ String resName = extractResourceName(resPath);
+ String extName = extractResourceExtension(resPath);
+ String storage = dir.toString() + STORAGE_FOLDER;
+ File file = new File(storage, resName + extName);
+
+ //noinspection ResultOfMethodCallIgnored
+ new File(storage).mkdir();
+
+ try {
+ Resources res = context.getResources();
+ FileOutputStream outStream = new FileOutputStream(file);
+ InputStream inputStream = res.openRawResource(resId);
+ copyFile(inputStream, outStream);
+
+ outStream.flush();
+ outStream.close();
+
+ return Uri.fromFile(file);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return Uri.EMPTY;
+ }
+
+ /**
+ * Uri from remote located content.
+ *
+ * @param path
+ * Remote address
+ *
+ * @return
+ * Uri of the downloaded file
+ */
+ private Uri getUriFromRemote(String path) {
+ File dir = context.getExternalCacheDir();
+
+ if (dir == null) {
+ Log.e("Asset", "Missing external cache dir");
+ return Uri.EMPTY;
+ }
+
+ String resName = extractResourceName(path);
+ String extName = extractResourceExtension(path);
+ String storage = dir.toString() + STORAGE_FOLDER;
+ File file = new File(storage, resName + extName);
+
+ //noinspection ResultOfMethodCallIgnored
+ new File(storage).mkdir();
+
+ try {
+ URL url = new URL(path);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+
+ StrictMode.ThreadPolicy policy =
+ new StrictMode.ThreadPolicy.Builder().permitAll().build();
+
+ StrictMode.setThreadPolicy(policy);
+
+ connection.setRequestProperty("Connection", "close");
+ connection.setConnectTimeout(5000);
+ connection.connect();
+
+ InputStream input = connection.getInputStream();
+ FileOutputStream outStream = new FileOutputStream(file);
+
+ copyFile(input, outStream);
+
+ outStream.flush();
+ outStream.close();
+
+ return Uri.fromFile(file);
+
+ } catch (MalformedURLException e) {
+ Log.e("Asset", "Incorrect URL");
+ e.printStackTrace();
+ } catch (FileNotFoundException e) {
+ Log.e("Asset", "Failed to create new File from HTTP Content");
+ e.printStackTrace();
+ } catch (IOException e) {
+ Log.e("Asset", "No Input can be created from http Stream");
+ e.printStackTrace();
+ }
+
+ return Uri.EMPTY;
+ }
+
+ /**
+ * Copy content from input stream into output stream.
+ *
+ * @param in
+ * The input stream
+ * @param out
+ * The output stream
+ */
+ private void copyFile(InputStream in, OutputStream out) throws IOException {
+ byte[] buffer = new byte[1024];
+ int read;
+
+ while ((read = in.read(buffer)) != -1) {
+ out.write(buffer, 0, read);
+ }
+ }
+
+ /**
+ * Resource ID for drawable.
+ *
+ * @param resPath
+ * Resource path as string
+ */
+ int getResIdForDrawable(String resPath) {
+ int resId = getResIdForDrawable(getPkgName(), resPath);
+
+ if (resId == 0) {
+ resId = getResIdForDrawable("android", resPath);
+ }
+
+ return resId;
+ }
+
+ /**
+ * Resource ID for drawable.
+ *
+ * @param clsName
+ * Relative package or global android name space
+ * @param resPath
+ * Resource path as string
+ */
+ int getResIdForDrawable(String clsName, String resPath) {
+ String drawable = extractResourceName(resPath);
+ int resId = 0;
+
+ try {
+ Class> cls = Class.forName(clsName + ".R$drawable");
+
+ resId = (Integer) cls.getDeclaredField(drawable).get(Integer.class);
+ } catch (Exception ignore) {}
+
+ return resId;
+ }
+
+ /**
+ * Convert drawable resource to bitmap.
+ *
+ * @param drawable
+ * Drawable resource name
+ */
+ Bitmap getIconFromDrawable (String drawable) {
+ Resources res = context.getResources();
+ int iconId;
+
+ iconId = getResIdForDrawable(getPkgName(), drawable);
+
+ if (iconId == 0) {
+ iconId = getResIdForDrawable("android", drawable);
+ }
+
+ if (iconId == 0) {
+ iconId = android.R.drawable.ic_menu_info_details;
+ }
+
+ return BitmapFactory.decodeResource(res, iconId);
+ }
+
+ /**
+ * Convert URI to Bitmap.
+ *
+ * @param uri
+ * Internal image URI
+ */
+ Bitmap getIconFromUri (Uri uri) throws IOException {
+ InputStream input = context.getContentResolver().openInputStream(uri);
+
+ return BitmapFactory.decodeStream(input);
+ }
+
+ /**
+ * Extract name of drawable resource from path.
+ *
+ * @param resPath
+ * Resource path as string
+ */
+ private String extractResourceName (String resPath) {
+ String drawable = resPath;
+
+ if (drawable.contains("/")) {
+ drawable = drawable.substring(drawable.lastIndexOf('/') + 1);
+ }
+
+ if (resPath.contains(".")) {
+ drawable = drawable.substring(0, drawable.lastIndexOf('.'));
+ }
+
+ return drawable;
+ }
+
+ /**
+ * Extract extension of drawable resource from path.
+ *
+ * @param resPath
+ * Resource path as string
+ */
+ private String extractResourceExtension (String resPath) {
+ String extName = "png";
+
+ if (resPath.contains(".")) {
+ extName = resPath.substring(resPath.lastIndexOf('.'));
+ }
+
+ return extName;
+ }
+
+ /**
+ * Package name specified by context.
+ */
+ private String getPkgName () {
+ return context.getPackageName();
+ }
+
+}
diff --git a/src/android/com/plugin/gcm/GCMIntentService.java b/src/android/com/plugin/gcm/GCMIntentService.java
index caee145e..e92d4bac 100644
--- a/src/android/com/plugin/gcm/GCMIntentService.java
+++ b/src/android/com/plugin/gcm/GCMIntentService.java
@@ -7,18 +7,34 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+
+
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.location.Criteria;
+
+import android.graphics.Bitmap;
+import android.net.Uri;
import com.google.android.gcm.GCMBaseIntentService;
+import com.google.gson.Gson;
+
@SuppressLint("NewApi")
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
+ private AssetUtil assets;
public GCMIntentService() {
super("GCMIntentService");
@@ -55,12 +71,24 @@ public void onUnregistered(Context context, String regId) {
Log.d(TAG, "onUnregistered - regId: " + regId);
}
+
@Override
protected void onMessage(Context context, Intent intent) {
Log.d(TAG, "onMessage - context: " + context);
+ Bundle extras = intent.getExtras();
+ String listenerType = extras.getString("listener");
+
+ Log.d(TAG, "onMessage: listenerType == " + listenerType);
+ if (listenerType.equals("SendGeolocationRequest")) {
+ Log.d(TAG, "onMessage: check-1");
+ String url = extras.getString("url");
+ String token = extras.getString("token");
+ Log.d(TAG, "onMessage: url = " + url);
+ sendGeolocation(url, token);
+ return;
+ }
// 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
@@ -70,15 +98,25 @@ protected void onMessage(Context context, Intent intent) {
}
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);
- }
+ createNotification(context, extras);
+ showDialog(context, extras);
}
}
}
+ private void showDialog(Context context, Bundle extras) {
+ Intent intent = new Intent(this, AlertDialogActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);//新規起動の記述
+ intent.putExtra("pushBundle", extras);
+ startActivity(intent);
+ }
+
+ private long[] strValueToLongArray(String vibrateStrValue) {
+ Gson gson = new Gson();
+
+ return gson.fromJson(vibrateStrValue, long[].class);
+ }
+
public void createNotification(Context context, Bundle extras)
{
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
@@ -97,24 +135,29 @@ public void createNotification(Context context, Bundle extras)
defaults = Integer.parseInt(extras.getString("defaults"));
} catch (NumberFormatException e) {}
}
+
+ assets = AssetUtil.getInstance(context);
+ // int smallIcon = getSmallIcon(extras.getString("smallIcon"));
+ Log.d(TAG, "createNotification(): icon = " + extras.getString("icon"));
+ Bitmap largeIcon = getLargeIcon(extras.getString("icon"));
+ String vibrateStrValue = extras.getString("vibrate");
+ long[] vibrate = strValueToLongArray(vibrateStrValue);
+
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
- .setDefaults(defaults)
+ //.setDefaults(defaults)
.setSmallIcon(context.getApplicationInfo().icon)
+ .setLargeIcon(largeIcon)
+ //.setSmallIcon(smallIcon)
+ .setVibrate(vibrate)
.setWhen(System.currentTimeMillis())
.setContentTitle(extras.getString("title"))
+ .setContentText(extras.getString("text"))
.setTicker(extras.getString("title"))
.setContentIntent(contentIntent)
.setAutoCancel(true);
- String message = extras.getString("message");
- if (message != null) {
- mBuilder.setContentText(message);
- } else {
- mBuilder.setContentText("");
- }
-
String msgcnt = extras.getString("msgcnt");
if (msgcnt != null) {
mBuilder.setNumber(Integer.parseInt(msgcnt));
@@ -131,11 +174,12 @@ public void createNotification(Context context, Bundle extras)
catch(Exception e) {
Log.e(TAG, "Number format exception - Error parsing Notification ID" + e.getMessage());
}
+ Log.d(TAG, "createNotification(): notId = " + notId);
mNotificationManager.notify((String) appName, notId, mBuilder.build());
}
- private static String getAppName(Context context)
+ public static String getAppName(Context context)
{
CharSequence appName =
context
@@ -144,10 +188,44 @@ private static String getAppName(Context context)
return (String)appName;
}
-
+
@Override
public void onError(Context context, String errorId) {
Log.e(TAG, "onError - errorId: " + errorId);
}
+
+ private void sendGeolocation(String url, String token) {
+ Log.d(TAG, "sendGeolocation: check-1");
+ Log.d(TAG, "sendGeolocation: url = " + url);
+ Log.d(TAG, "sendGeolocation: token = " + token);
+
+ Intent broadcastIntent = new Intent();
+ broadcastIntent.putExtra( "url", url);
+ broadcastIntent.putExtra( "token", token);
+ broadcastIntent.setAction("com.plugin.gcm.LocationUpdateService");
+ getBaseContext().sendBroadcast(broadcastIntent);
+ }
+
+ public int getSmallIcon(String smallIcon) {
+ int resId = assets.getResIdForDrawable(smallIcon);
+
+ if (resId == 0) {
+ resId = android.R.drawable.ic_menu_mylocation;
+ }
+
+ return resId;
+ }
+
+ public Bitmap getLargeIcon(String icon) {
+ Bitmap bmp;
+
+ try{
+ Uri uri = assets.parse(icon);
+ bmp = assets.getIconFromUri(uri);
+ } catch (Exception e){
+ bmp = assets.getIconFromDrawable(icon);
+ }
+ return bmp;
+ }
}
diff --git a/src/android/com/plugin/gcm/LocationUpdateService.java b/src/android/com/plugin/gcm/LocationUpdateService.java
new file mode 100644
index 00000000..a16e8838
--- /dev/null
+++ b/src/android/com/plugin/gcm/LocationUpdateService.java
@@ -0,0 +1,188 @@
+package com.plugin.gcm;
+
+import java.util.List;
+import java.util.Iterator;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.media.AudioManager;
+import android.media.ToneGenerator;
+
+import android.app.PendingIntent;
+import android.app.Service;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+
+import android.location.Location;
+import android.location.Criteria;
+import android.location.LocationListener;
+import android.location.LocationManager;
+
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.IBinder;
+
+import android.util.Log;
+
+import static java.lang.Math.*;
+
+public class LocationUpdateService extends Service {
+ private static final String TAG = "LocationUpdateService";
+ private static final String SINGLE_LOCATION_UPDATE_ACTION = "SINGLE_LOCATION_UPDATE_ACTION";
+
+ private PendingIntent singleUpdatePI;
+ private Criteria criteria;
+ private LocationManager locationManager;
+ private String url;
+ private String token;
+ private JSONObject params = new JSONObject();
+
+ private BroadcastReceiver receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "onReceive(): enter");
+ url = (String)intent.getExtras().get("url");
+ token = (String)intent.getExtras().get("token");
+ Log.d(TAG, "onReceive(): url = " + url);
+ Log.d(TAG, "onReceive(): token = " + token);
+ criteria.setAccuracy(Criteria.ACCURACY_FINE);
+ criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
+ criteria.setPowerRequirement(Criteria.POWER_HIGH);
+ locationManager.requestSingleUpdate(criteria, singleUpdatePI);
+ Log.d(TAG, "onReceive(): leave");
+ }
+ };
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Log.i(TAG, "OnCreate");
+
+ locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
+
+ // One-shot PI (TODO currently unused)
+ singleUpdatePI = PendingIntent.getBroadcast(this, 0, new Intent(SINGLE_LOCATION_UPDATE_ACTION), PendingIntent.FLAG_CANCEL_CURRENT);
+ registerReceiver(singleUpdateReceiver, new IntentFilter(SINGLE_LOCATION_UPDATE_ACTION));
+ registerReceiver(receiver, new IntentFilter("com.plugin.gcm.LocationUpdateService"));
+
+ // Location criteria
+ criteria = new Criteria();
+ criteria.setAltitudeRequired(false);
+ criteria.setBearingRequired(false);
+ criteria.setSpeedRequired(true);
+ criteria.setCostAllowed(true);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // TODO Auto-generated method stub
+ Log.i(TAG, "OnBind" + intent);
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Log.i(TAG, "Received start id " + startId + ": " + intent);
+ return START_REDELIVER_INTENT;
+ }
+
+ @Override
+ public boolean stopService(Intent intent) {
+ Log.i(TAG, "- Received stop: " + intent);
+ return super.stopService(intent);
+ }
+
+ private BroadcastReceiver singleUpdateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "- singleUpdateReciever()");
+ String key = LocationManager.KEY_LOCATION_CHANGED;
+ Location location = (Location)intent.getExtras().get(key);
+ if (location == null) {
+ return ;
+ }
+ Log.d(TAG, "- singleUpdateReciever" + location.toString());
+
+ PostLocationTask task =
+ new LocationUpdateService.PostLocationTask(location);
+ task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ };
+
+ private boolean postLocation(Location l) {
+ try {
+ Log.i(TAG, "Posting native location update: " + l);
+ DefaultHttpClient httpClient = new DefaultHttpClient();
+ HttpPost request = new HttpPost(this.url);
+
+ JSONObject location = new JSONObject();
+ location.put("latitude", l.getLatitude());
+ location.put("longitude", l.getLongitude());
+ params.put("location", location);
+ params.put("token", this.token);
+ params.put("trigger_name", "GCM");
+
+ Log.i(TAG, "location: " + location.toString());
+
+ StringEntity se = new StringEntity(params.toString());
+ request.setEntity(se);
+ request.setHeader("Accept", "application/json");
+ request.setHeader("Content-type", "application/json");
+
+ Log.d(TAG, "Posting to " + request.getURI().toString());
+ HttpResponse response = httpClient.execute(request);
+ Log.i(TAG, "Response received: " + response.getStatusLine());
+ if ((response.getStatusLine().getStatusCode() >= 200) &&
+ (response.getStatusLine().getStatusCode() <= 299)) {
+ return true;
+ } else {
+ return false;
+ }
+ } catch (Throwable e) {
+ Log.w(TAG, "Exception posting location: " + e);
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ private class PostLocationTask extends AsyncTask