Updated Branches: refs/heads/master [created] e91dd49b6
Initial Commit Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/commit/e91dd49b Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/tree/e91dd49b Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/diff/e91dd49b Branch: refs/heads/master Commit: e91dd49b6d1cba9cef1c04640f3927c3c6581bf9 Parents: Author: Joe Bowser <[email protected]> Authored: Tue Apr 2 16:11:35 2013 -0700 Committer: Joe Bowser <[email protected]> Committed: Tue Apr 2 16:11:35 2013 -0700 ---------------------------------------------------------------------- README.md | 2 + plugin.xml | 22 +++ src/android/CordovaLocationListener.java | 207 +++++++++++++++++++++++++ src/android/GPSListener.java | 51 ++++++ src/android/GeoBroker.java | 204 ++++++++++++++++++++++++ src/android/NetworkListener.java | 33 ++++ 6 files changed, 519 insertions(+), 0 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/blob/e91dd49b/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md new file mode 100644 index 0000000..be5927a --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +cordova-plugin-geolocation +--------------------------- http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/blob/e91dd49b/plugin.xml ---------------------------------------------------------------------- diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..7998a69 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" +xmlns:android="http://schemas.android.com/apk/res/android" +id="org.apache.cordova.core"> + version="0.1.0"> + <name>Geolocation</name> + + <!-- android --> + <platform name="android"> + <config-file target="res/xml/config.xml" parent="/cordova/plugins"> + <plugin name="Geolocation" value="org.apache.cordova.core.GeoBroker"/> + </config-file> + + <source-file src="GeoBroker.java" target-dir="org/apache/cordova/core" /> + <source-file src="GPSListener.java" target-dir="org/apache/cordova/core" /> + <source-file src="NetworkListener.java" target-dir="org/apache/cordova/core" /> + <source-file src="CordovaLocationListener.java" target-dir="org/apache/cordova/core" /> + <source-file src="GeoBroker.java" target-dir="org/apache/cordova/core" /> + + </platform> +</plugin> http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/blob/e91dd49b/src/android/CordovaLocationListener.java ---------------------------------------------------------------------- diff --git a/src/android/CordovaLocationListener.java b/src/android/CordovaLocationListener.java new file mode 100755 index 0000000..86ba989 --- /dev/null +++ b/src/android/CordovaLocationListener.java @@ -0,0 +1,207 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ +package org.apache.cordova.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import org.apache.cordova.api.CallbackContext; + +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; +import android.util.Log; + +public class CordovaLocationListener implements LocationListener { + public static int PERMISSION_DENIED = 1; + public static int POSITION_UNAVAILABLE = 2; + public static int TIMEOUT = 3; + + protected LocationManager locationManager; + private GeoBroker owner; + protected boolean running = false; + + public HashMap<String, CallbackContext> watches = new HashMap<String, CallbackContext>(); + private List<CallbackContext> callbacks = new ArrayList<CallbackContext>(); + + private String TAG = "[Cordova Location Listener]"; + + public CordovaLocationListener(LocationManager manager, GeoBroker broker, String tag) { + this.locationManager = manager; + this.owner = broker; + this.TAG = tag; + } + + protected void fail(int code, String message) { + for (CallbackContext callbackContext: this.callbacks) + { + this.owner.fail(code, message, callbackContext); + } + if(this.owner.isGlobalListener(this)) + { + Log.d(TAG, "Stopping global listener"); + this.stop(); + } + this.callbacks.clear(); + + Iterator<CallbackContext> it = this.watches.values().iterator(); + while (it.hasNext()) { + this.owner.fail(code, message, it.next()); + } + } + + private void win(Location loc) { + for (CallbackContext callbackContext: this.callbacks) + { + this.owner.win(loc, callbackContext); + } + if(this.owner.isGlobalListener(this)) + { + Log.d(TAG, "Stopping global listener"); + this.stop(); + } + this.callbacks.clear(); + + Iterator<CallbackContext> it = this.watches.values().iterator(); + while (it.hasNext()) { + this.owner.win(loc, it.next()); + } + } + + /** + * Location Listener Methods + */ + + /** + * Called when the provider is disabled by the user. + * + * @param provider + */ + public void onProviderDisabled(String provider) { + Log.d(TAG, "Location provider '" + provider + "' disabled."); + this.fail(POSITION_UNAVAILABLE, "GPS provider disabled."); + } + + /** + * Called when the provider is enabled by the user. + * + * @param provider + */ + public void onProviderEnabled(String provider) { + Log.d(TAG, "Location provider "+ provider + " has been enabled"); + } + + /** + * Called when the provider status changes. This method is called when a + * provider is unable to fetch a location or if the provider has recently + * become available after a period of unavailability. + * + * @param provider + * @param status + * @param extras + */ + public void onStatusChanged(String provider, int status, Bundle extras) { + Log.d(TAG, "The status of the provider " + provider + " has changed"); + if (status == 0) { + Log.d(TAG, provider + " is OUT OF SERVICE"); + this.fail(CordovaLocationListener.POSITION_UNAVAILABLE, "Provider " + provider + " is out of service."); + } + else if (status == 1) { + Log.d(TAG, provider + " is TEMPORARILY_UNAVAILABLE"); + } + else { + Log.d(TAG, provider + " is AVAILABLE"); + } + } + + /** + * Called when the location has changed. + * + * @param location + */ + public void onLocationChanged(Location location) { + Log.d(TAG, "The location has been updated!"); + this.win(location); + } + + // PUBLIC + + public int size() { + return this.watches.size() + this.callbacks.size(); + } + + public void addWatch(String timerId, CallbackContext callbackContext) { + this.watches.put(timerId, callbackContext); + if (this.size() == 1) { + this.start(); + } + } + public void addCallback(CallbackContext callbackContext) { + this.callbacks.add(callbackContext); + if (this.size() == 1) { + this.start(); + } + } + public void clearWatch(String timerId) { + if (this.watches.containsKey(timerId)) { + this.watches.remove(timerId); + } + if (this.size() == 0) { + this.stop(); + } + } + + /** + * Destroy listener. + */ + public void destroy() { + this.stop(); + } + + // LOCAL + + /** + * Start requesting location updates. + * + * @param interval + */ + protected void start() { + if (!this.running) { + if (this.locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) { + this.running = true; + this.locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 10, this); + } else { + this.fail(CordovaLocationListener.POSITION_UNAVAILABLE, "Network provider is not available."); + } + } + } + + /** + * Stop receiving location updates. + */ + private void stop() { + if (this.running) { + this.locationManager.removeUpdates(this); + this.running = false; + } + } +} http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/blob/e91dd49b/src/android/GPSListener.java ---------------------------------------------------------------------- diff --git a/src/android/GPSListener.java b/src/android/GPSListener.java new file mode 100755 index 0000000..ba26dae --- /dev/null +++ b/src/android/GPSListener.java @@ -0,0 +1,51 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +package org.apache.cordova.core; + + +import android.location.LocationManager; + +/** + * This class handles requests for GPS location services. + * + */ +public class GPSListener extends CordovaLocationListener { + public GPSListener(LocationManager locationManager, GeoBroker m) { + super(locationManager, m, "[Cordova GPSListener]"); + } + + + /** + * Start requesting location updates. + * + * @param interval + */ + @Override + protected void start() { + if (!this.running) { + if (this.locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) { + this.running = true; + this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 0, this); + } else { + this.fail(CordovaLocationListener.POSITION_UNAVAILABLE, "GPS provider is not available."); + } + } + } +} http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/blob/e91dd49b/src/android/GeoBroker.java ---------------------------------------------------------------------- diff --git a/src/android/GeoBroker.java b/src/android/GeoBroker.java new file mode 100755 index 0000000..8bcfb32 --- /dev/null +++ b/src/android/GeoBroker.java @@ -0,0 +1,204 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ +package org.apache.cordova.core; + +import org.apache.cordova.api.CallbackContext; +import org.apache.cordova.api.CordovaPlugin; +import org.apache.cordova.api.PluginResult; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.content.Context; +import android.location.Location; +import android.location.LocationManager; + +/* + * This class is the interface to the Geolocation. It's bound to the geo object. + * + * This class only starts and stops various GeoListeners, which consist of a GPS and a Network Listener + */ + +public class GeoBroker extends CordovaPlugin { + private GPSListener gpsListener; + private NetworkListener networkListener; + private LocationManager locationManager; + + /** + * Constructor. + */ + public GeoBroker() { + } + + /** + * Executes the request and returns PluginResult. + * + * @param action The action to execute. + * @param args JSONArry of arguments for the plugin. + * @param callbackContext The callback id used when calling back into JavaScript. + * @return True if the action was valid, or false if not. + */ + public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { + if (this.locationManager == null) { + this.locationManager = (LocationManager) this.cordova.getActivity().getSystemService(Context.LOCATION_SERVICE); + this.networkListener = new NetworkListener(this.locationManager, this); + this.gpsListener = new GPSListener(this.locationManager, this); + } + + if ( locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) || + locationManager.isProviderEnabled( LocationManager.NETWORK_PROVIDER )) { + + if (action.equals("getLocation")) { + boolean enableHighAccuracy = args.getBoolean(0); + int maximumAge = args.getInt(1); + Location last = this.locationManager.getLastKnownLocation((enableHighAccuracy ? LocationManager.GPS_PROVIDER : LocationManager.NETWORK_PROVIDER)); + // Check if we can use lastKnownLocation to get a quick reading and use less battery + if (last != null && (System.currentTimeMillis() - last.getTime()) <= maximumAge) { + PluginResult result = new PluginResult(PluginResult.Status.OK, this.returnLocationJSON(last)); + callbackContext.sendPluginResult(result); + } else { + this.getCurrentLocation(callbackContext, enableHighAccuracy); + } + } + else if (action.equals("addWatch")) { + String id = args.getString(0); + boolean enableHighAccuracy = args.getBoolean(1); + this.addWatch(id, callbackContext, enableHighAccuracy); + } + else if (action.equals("clearWatch")) { + String id = args.getString(0); + this.clearWatch(id); + } + else { + return false; + } + } else { + PluginResult.Status status = PluginResult.Status.NO_RESULT; + String message = "Location API is not available for this device."; + PluginResult result = new PluginResult(status, message); + callbackContext.sendPluginResult(result); + } + return true; + } + + private void clearWatch(String id) { + this.gpsListener.clearWatch(id); + this.networkListener.clearWatch(id); + } + + private void getCurrentLocation(CallbackContext callbackContext, boolean enableHighAccuracy) { + if (enableHighAccuracy) { + this.gpsListener.addCallback(callbackContext); + } else { + this.networkListener.addCallback(callbackContext); + } + } + + private void addWatch(String timerId, CallbackContext callbackContext, boolean enableHighAccuracy) { + if (enableHighAccuracy) { + this.gpsListener.addWatch(timerId, callbackContext); + } else { + this.networkListener.addWatch(timerId, callbackContext); + } + } + + /** + * Called when the activity is to be shut down. + * Stop listener. + */ + public void onDestroy() { + if (this.networkListener != null) { + this.networkListener.destroy(); + this.networkListener = null; + } + if (this.gpsListener != null) { + this.gpsListener.destroy(); + this.gpsListener = null; + } + } + + /** + * Called when the view navigates. + * Stop the listeners. + */ + public void onReset() { + this.onDestroy(); + } + + public JSONObject returnLocationJSON(Location loc) { + JSONObject o = new JSONObject(); + + try { + o.put("latitude", loc.getLatitude()); + o.put("longitude", loc.getLongitude()); + o.put("altitude", (loc.hasAltitude() ? loc.getAltitude() : null)); + o.put("accuracy", loc.getAccuracy()); + o.put("heading", (loc.hasBearing() ? (loc.hasSpeed() ? loc.getBearing() : null) : null)); + o.put("velocity", loc.getSpeed()); + o.put("timestamp", loc.getTime()); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return o; + } + + public void win(Location loc, CallbackContext callbackContext) { + PluginResult result = new PluginResult(PluginResult.Status.OK, this.returnLocationJSON(loc)); + callbackContext.sendPluginResult(result); + } + + /** + * Location failed. Send error back to JavaScript. + * + * @param code The error code + * @param msg The error message + * @throws JSONException + */ + public void fail(int code, String msg, CallbackContext callbackContext) { + JSONObject obj = new JSONObject(); + String backup = null; + try { + obj.put("code", code); + obj.put("message", msg); + } catch (JSONException e) { + obj = null; + backup = "{'code':" + code + ",'message':'" + msg.replaceAll("'", "\'") + "'}"; + } + PluginResult result; + if (obj != null) { + result = new PluginResult(PluginResult.Status.ERROR, obj); + } else { + result = new PluginResult(PluginResult.Status.ERROR, backup); + } + + callbackContext.sendPluginResult(result); + } + + public boolean isGlobalListener(CordovaLocationListener listener) + { + if (gpsListener != null && networkListener != null) + { + return gpsListener.equals(listener) || networkListener.equals(listener); + } + else + return false; + } +} http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation/blob/e91dd49b/src/android/NetworkListener.java ---------------------------------------------------------------------- diff --git a/src/android/NetworkListener.java b/src/android/NetworkListener.java new file mode 100755 index 0000000..eadf91a --- /dev/null +++ b/src/android/NetworkListener.java @@ -0,0 +1,33 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +package org.apache.cordova.core; + + +import android.location.LocationManager; + +/** + * This class handles requests for GPS location services. + * + */ +public class NetworkListener extends CordovaLocationListener { + public NetworkListener(LocationManager locationManager, GeoBroker m) { + super(locationManager, m, "[Cordova NetworkListener]"); + } +}
