diff --git a/Android/BluetoothPlugin/LICENSE b/Android/BluetoothPlugin/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/Android/BluetoothPlugin/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
diff --git a/Android/BluetoothPlugin/NOTICE b/Android/BluetoothPlugin/NOTICE
new file mode 100644
index 0000000..fc541a8
--- /dev/null
+++ b/Android/BluetoothPlugin/NOTICE
@@ -0,0 +1,13 @@
+ Copyright 2012 Wolfgang Koller - http://www.gofg.at/
+
+ Licensed 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.
\ No newline at end of file
diff --git a/Android/BluetoothPlugin/README.md b/Android/BluetoothPlugin/README.md
new file mode 100644
index 0000000..1fc366d
--- /dev/null
+++ b/Android/BluetoothPlugin/README.md
@@ -0,0 +1,37 @@
+Bluetooth
+===============
+Plugin for PhoneGap
+
+The Bluetooth plugin offers access to the devices bluetooth functionality.
+Useful for any application requiring interaction with the bluetooth stack.
+
+Platforms
+---------
+Currently available on:
+
+### Android
+Copy the *BluetoothPlugin.java* file to your *src/* directory.
+
+Edit your *AndroidManifest.xml* and add the following permissions:
+``
+``
+
+In addition you have to edit your *res/xml/plugins.xml* file to let PhoneGap know about the plugin:
+``
+
+
+License
+=======
+ Copyright 2012 Wolfgang Koller - http://www.gofg.at/
+
+ Licensed 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.
diff --git a/Android/BluetoothPlugin/assets/www/bluetooth.js b/Android/BluetoothPlugin/assets/www/bluetooth.js
new file mode 100644
index 0000000..0b45f81
--- /dev/null
+++ b/Android/BluetoothPlugin/assets/www/bluetooth.js
@@ -0,0 +1,93 @@
+/*
+ Copyright 2012 Wolfgang Koller - http://www.gofg.at/
+
+ Licensed 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.
+*/
+
+if( !PhoneGap.hasResource("BluetoothPlugin") ) {
+ PhoneGap.addResource("BluetoothPlugin");
+
+ /**
+ * @returns instance of powermanagement
+ */
+ var Bluetooth = function() {
+ }
+
+ /**
+ * Enable bluetooth
+ *
+ * @param successCallback function to be called when enabling of bluetooth was successfull
+ * @param errorCallback function to be called when enabling was not possible / did fail
+ */
+ Bluetooth.prototype.enable = function(successCallback,failureCallback) {
+ return PhoneGap.exec(successCallback, failureCallback, 'BluetoothPlugin', 'enable', []);
+ }
+
+ /**
+ * Disable bluetooth
+ *
+ * @param successCallback function to be called when disabling of bluetooth was successfull
+ * @param errorCallback function to be called when disabling was not possible / did fail
+ */
+ Bluetooth.prototype.disable = function(successCallback,failureCallback) {
+ return PhoneGap.exec(successCallback, failureCallback, 'BluetoothPlugin', 'disable', []);
+ }
+
+ /**
+ * Search for devices and list them
+ *
+ * @param successCallback function to be called when discovery of other devices has finished. Passed parameter is a JSONArray containing JSONObjects with 'name' and 'address' property.
+ * @param errorCallback function to be called when there was a problem while discovering devices
+ */
+ Bluetooth.prototype.discoverDevices = function(successCallback,failureCallback) {
+ return PhoneGap.exec(successCallback, failureCallback, 'BluetoothPlugin', 'discoverDevices', []);
+ }
+
+ /**
+ * Return list of available UUIDs for a given device
+ *
+ * @param successCallback function to be called when listing of UUIDs has finished. Passed parameter is a JSONArray containing strings which represent the UUIDs
+ * @param errorCallback function to be called when there was a problem while listing UUIDs
+ */
+ Bluetooth.prototype.getUUIDs = function(successCallback,failureCallback,address) {
+ return PhoneGap.exec(successCallback, failureCallback, 'BluetoothPlugin', 'getUUIDs', [address]);
+ }
+
+ /**
+ * Open an RFComm channel for a given device & uuid endpoint
+ *
+ * @param successCallback function to be called when the connection was successfull. Passed parameter is an integer containing the socket id for the connection
+ * @param errorCallback function to be called when there was a problem while opening the connection
+ */
+ Bluetooth.prototype.connect = function(successCallback,failureCallback,address,uuid) {
+ return PhoneGap.exec(successCallback, failureCallback, 'BluetoothPlugin', 'connect', [address, uuid]);
+ }
+
+ /**
+ * Read from a connected socket
+ *
+ * @param successCallback function to be called when reading was successfull. Passed parameter is a string containing the read content
+ * @param errorCallback function to be called when there was a problem while reading
+ */
+ Bluetooth.prototype.read = function(successCallback,failureCallback,socketid) {
+ return PhoneGap.exec(successCallback, failureCallback, 'BluetoothPlugin', 'read', [socketid]);
+ }
+
+ /**
+ * Register the plugin with PhoneGap
+ */
+ PhoneGap.addConstructor(function() {
+ // Register the PowerManagement plugin with PhoneGap
+ PhoneGap.addPlugin('BluetoothPlugin', new Bluetooth());
+ });
+}
diff --git a/Android/BluetoothPlugin/src/com/phonegap/plugin/BluetoothPlugin.java b/Android/BluetoothPlugin/src/com/phonegap/plugin/BluetoothPlugin.java
new file mode 100644
index 0000000..bc19972
--- /dev/null
+++ b/Android/BluetoothPlugin/src/com/phonegap/plugin/BluetoothPlugin.java
@@ -0,0 +1,285 @@
+/*
+ Copyright 2012 Wolfgang Koller - http://www.gofg.at/
+
+ Licensed 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 com.phonegap.plugin;
+
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.UUID;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.phonegap.api.PhonegapActivity;
+import com.phonegap.api.Plugin;
+import com.phonegap.api.PluginResult;
+
+public class BluetoothPlugin extends Plugin {
+ private static final String ACTION_ENABLE = "enable";
+ private static final String ACTION_DISABLE = "disable";
+ private static final String ACTION_DISCOVERDEVICES = "discoverDevices";
+ private static final String ACTION_GETUUIDS = "getUUIDs";
+ private static final String ACTION_CONNECT = "connect";
+ private static final String ACTION_READ = "read";
+
+ private static String ACTION_UUID = "";
+ private static String EXTRA_UUID = "";
+
+ private BluetoothAdapter m_bluetoothAdapter = null;
+ private BPBroadcastReceiver m_bpBroadcastReceiver = null;
+ private boolean m_discovering = false;
+ private boolean m_gettingUuids = false;
+ private boolean m_stateChanging = false;
+
+ private JSONArray m_discoveredDevices = null;
+ private JSONArray m_gotUUIDs = null;
+ private boolean m_enabled = false;
+
+ private ArrayList m_bluetoothSockets = new ArrayList();
+
+ public BluetoothPlugin() {
+ m_bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ m_bpBroadcastReceiver = new BPBroadcastReceiver();
+
+ try {
+ Field actionUUID = BluetoothDevice.class.getDeclaredField("ACTION_UUID");
+ BluetoothPlugin.ACTION_UUID = (String) actionUUID.get(null);
+ Log.d("BluetoothPlugin", "actionUUID: " + actionUUID.getName() + " / " + actionUUID.get(null));
+
+ Field extraUUID = BluetoothDevice.class.getDeclaredField("EXTRA_UUID");
+ BluetoothPlugin.EXTRA_UUID = (String) extraUUID.get(null);
+ Log.d("BluetoothPlugin", "extraUUID: " + extraUUID.getName() + " / " + extraUUID.get(null));
+ }
+ catch( Exception e ) {
+ Log.e("BluetoothPlugin", e.getMessage() );
+ }
+
+ }
+
+ @Override
+ public void setContext(PhonegapActivity ctx) {
+ super.setContext(ctx);
+
+ // Register for necessary bluetooth events
+ ctx.registerReceiver(m_bpBroadcastReceiver, new IntentFilter(
+ BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
+ ctx.registerReceiver(m_bpBroadcastReceiver, new IntentFilter(
+ BluetoothDevice.ACTION_FOUND));
+ ctx.registerReceiver(m_bpBroadcastReceiver, new IntentFilter(BluetoothPlugin.ACTION_UUID));
+ ctx.registerReceiver(m_bpBroadcastReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
+
+ }
+
+ @Override
+ public PluginResult execute(String action, JSONArray data, String callbackId) {
+ PluginResult pluginResult = null;
+
+ Log.d("BluetoothPlugin", "Action: " + action);
+
+ // Want to enable bluetooth?
+ if (ACTION_ENABLE.equals(action)) {
+ m_stateChanging = true;
+ ctx.startActivity(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE));
+ while(m_stateChanging) {};
+
+ // Check if bluetooth is enabled now
+ if(m_enabled) {
+ pluginResult = new PluginResult(PluginResult.Status.OK);
+ }
+ else {
+ pluginResult = new PluginResult(PluginResult.Status.ERROR);
+ }
+ }
+ // Want to disable bluetooth?
+ else if (ACTION_DISABLE.equals(action)) {
+ m_stateChanging = true;
+ if( !m_bluetoothAdapter.disable() && m_bluetoothAdapter.isEnabled() ) {
+ pluginResult = new PluginResult(PluginResult.Status.ERROR);
+ }
+ else {
+ while(m_stateChanging) {};
+
+ // Check if bluetooth is disabled now
+ if(!m_enabled) {
+ pluginResult = new PluginResult(PluginResult.Status.OK);
+ }
+ else {
+ pluginResult = new PluginResult(PluginResult.Status.ERROR);
+ }
+ }
+
+ }
+ else if (ACTION_DISCOVERDEVICES.equals(action)) {
+ m_discoveredDevices = new JSONArray();
+
+ if (!m_bluetoothAdapter.startDiscovery()) {
+ pluginResult = new PluginResult(PluginResult.Status.ERROR,
+ "Unable to start discovery");
+ } else {
+ m_discovering = true;
+
+ // Wait for discovery to finish
+ while (m_discovering) {}
+
+ Log.d("BluetoothPlugin", "DiscoveredDevices: " + m_discoveredDevices.length());
+
+ pluginResult = new PluginResult(PluginResult.Status.OK, m_discoveredDevices);
+ }
+ }
+ // Want to list UUIDs of a certain device
+ else if( ACTION_GETUUIDS.equals(action) ) {
+
+ try {
+ String address = data.getString(0);
+ Log.d("BluetoothPlugin", "Listing UUIDs for: " + address);
+
+ // Fetch UUIDs from bluetooth device
+ BluetoothDevice bluetoothDevice = m_bluetoothAdapter.getRemoteDevice(address);
+ Method m = bluetoothDevice.getClass().getMethod("fetchUuidsWithSdp");
+ Log.d("BluetoothPlugin", "Method: " + m);
+ m.invoke(bluetoothDevice);
+
+ m_gettingUuids = true;
+
+ while(m_gettingUuids) {}
+
+ pluginResult = new PluginResult(PluginResult.Status.OK, m_gotUUIDs);
+
+ }
+ catch( Exception e ) {
+ Log.e("BluetoothPlugin", e.toString() + " / " + e.getMessage() );
+
+ pluginResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
+ }
+ }
+ // Connect to a given device & uuid endpoint
+ else if( ACTION_CONNECT.equals(action) ) {
+ try {
+ String address = data.getString(0);
+ UUID uuid = UUID.fromString(data.getString(1));
+
+ BluetoothDevice bluetoothDevice = m_bluetoothAdapter.getRemoteDevice(address);
+ BluetoothSocket bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
+
+ bluetoothSocket.connect();
+
+ m_bluetoothSockets.add(bluetoothSocket);
+ int socketId = m_bluetoothSockets.indexOf(bluetoothSocket);
+
+ pluginResult = new PluginResult(PluginResult.Status.OK, socketId);
+ }
+ catch( Exception e ) {
+ Log.e("BluetoothPlugin", e.toString() + " / " + e.getMessage() );
+
+ pluginResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
+ }
+ }
+ else if( ACTION_READ.equals(action) ) {
+ try {
+ int socketId = data.getInt(0);
+
+ BluetoothSocket bluetoothSocket = m_bluetoothSockets.get(socketId);
+ InputStream inputStream = bluetoothSocket.getInputStream();
+
+ char[] buffer = new char[128];
+ for( int i = 0; i < buffer.length; i++ ) {
+ buffer[i] = (char) inputStream.read();
+ }
+
+ Log.d( "BluetoothPlugin", "Buffer: " + String.valueOf(buffer) );
+ pluginResult = new PluginResult(PluginResult.Status.OK, String.valueOf(buffer));
+ }
+ catch( Exception e ) {
+ Log.e("BluetoothPlugin", e.toString() + " / " + e.getMessage() );
+
+ pluginResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
+ }
+ }
+
+ // TODO Auto-generated method stub
+ return pluginResult;
+ }
+
+ private class BPBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ // Check if we found a new device
+ if (BluetoothDevice.ACTION_FOUND.equals(action)) {
+ BluetoothDevice bluetoothDevice = intent
+ .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+ try {
+ JSONObject deviceInfo = new JSONObject();
+ deviceInfo.put("name", bluetoothDevice.getName());
+ deviceInfo.put("address", bluetoothDevice.getAddress());
+
+ m_discoveredDevices.put(deviceInfo);
+ } catch (JSONException e) {
+ Log.e("BluetoothPlugin", e.getMessage());
+ }
+ }
+ // Check if we finished discovering devices
+ else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
+ m_discovering = false;
+ }
+ // Check if we found UUIDs
+ else if(BluetoothPlugin.ACTION_UUID.equals(action)) {
+ m_gotUUIDs = new JSONArray();
+
+ Parcelable[] parcelUuids = intent.getParcelableArrayExtra(BluetoothPlugin.EXTRA_UUID);
+ if( parcelUuids != null ) {
+ Log.d("BluetoothPlugin", "Found UUIDs: " + parcelUuids.length);
+
+ // Sort UUIDs into JSON array and return it
+ for( int i = 0; i < parcelUuids.length; i++ ) {
+ m_gotUUIDs.put( parcelUuids[i].toString() );
+ }
+
+ m_gettingUuids = false;
+ }
+ }
+ else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
+ int adapterState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+ Log.d("BluetoothPlugin", "State changed: " + adapterState);
+
+ if(adapterState == BluetoothAdapter.STATE_ON) {
+ m_enabled = true;
+ m_stateChanging = false;
+ }
+ else if(adapterState == BluetoothAdapter.STATE_OFF) {
+ m_enabled = false;
+ m_stateChanging = false;
+ }
+ }
+ }
+ };
+
+}
diff --git a/Android/PowerManagement/README.md b/Android/PowerManagement/README.md
index feb2b93..2e97442 100644
--- a/Android/PowerManagement/README.md
+++ b/Android/PowerManagement/README.md
@@ -1,6 +1,6 @@
PowerManagement
===============
-Plugin for PhoneGap
+Plugin for Cordova (1.6+)
The PowerManagement plugin offers access to the devices power-management functionality.
It should be used for applications which keep running for a long time without any user interaction.
@@ -21,7 +21,7 @@ Edit your *AndroidManifest.xml* and add the following permission:
``
In addition you have to edit your *res/xml/plugins.xml* file to let PhoneGap know about the plugin:
-``
+``
### iOS
Copy the *PowerManagement.h* and *PowerManagement.m* files to your project.
@@ -32,7 +32,7 @@ See http://wiki.phonegap.com/w/page/41733808/PhoneGap-iOS-Plugins-Problems
License
=======
-Copyright (C) 2011 Wolfgang Koller
+Copyright (C) 2011-2012 Wolfgang Koller
This file is part of GOFG Sports Computer - http://www.gofg.at/.
diff --git a/Android/PowerManagement/assets/www/index.html b/Android/PowerManagement/assets/www/index.html
new file mode 100644
index 0000000..162983b
--- /dev/null
+++ b/Android/PowerManagement/assets/www/index.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Android/PowerManagement/assets/www/powermanagement.js b/Android/PowerManagement/assets/www/powermanagement.js
index 42c706b..e3705e5 100644
--- a/Android/PowerManagement/assets/www/powermanagement.js
+++ b/Android/PowerManagement/assets/www/powermanagement.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Wolfgang Koller
+ * Copyright (C) 2011-2012 Wolfgang Koller
*
* This file is part of GOFG Sports Computer - http://www.gofg.at/.
*
@@ -17,14 +17,10 @@
* along with GOFG Sports Computer. If not, see .
*/
-if( !PhoneGap.hasResource("PowerManagement") ) {
- PhoneGap.addResource("PowerManagement");
-
- /**
- * @returns instance of powermanagement
- */
- var PowerManagement = function() {
- }
+cordova.define("cordova/plugin/powermanagement", function(require, exports, module) {
+ var exec = require('cordova/exec');
+
+ var PowerManagement = function() {};
/**
* Acquire a new wake-lock (keep device awake)
@@ -33,9 +29,9 @@ if( !PhoneGap.hasResource("PowerManagement") ) {
* @param errorCallback function to be called when there was a problem with acquiring the wake-lock
*/
PowerManagement.prototype.acquire = function(successCallback,failureCallback) {
- return PhoneGap.exec(successCallback, failureCallback, 'PowerManagement', 'acquire', []);
+ exec(successCallback, failureCallback, 'PowerManagement', 'acquire', []);
}
-
+
/**
* Release the wake-lock
*
@@ -43,9 +39,9 @@ if( !PhoneGap.hasResource("PowerManagement") ) {
* @param errorCallback function to be called when there was a problem while releasing the wake-lock
*/
PowerManagement.prototype.release = function(successCallback,failureCallback) {
- return PhoneGap.exec(successCallback, failureCallback, 'PowerManagement', 'release', []);
+ exec(successCallback, failureCallback, 'PowerManagement', 'release', []);
}
-
+
/**
* Acquire a partial wake-lock, allowing the device to dim the screen
*
@@ -53,14 +49,9 @@ if( !PhoneGap.hasResource("PowerManagement") ) {
* @param errorCallback function to be called when there was a problem with acquiring the wake-lock
*/
PowerManagement.prototype.dim = function(successCallback,failureCallback) {
- return PhoneGap.exec(successCallback, failureCallback, 'PowerManagement', 'acquire', [true]);
+ exec(successCallback, failureCallback, 'PowerManagement', 'acquire', [true]);
}
- /**
- * Register the plugin with PhoneGap
- */
- PhoneGap.addConstructor(function() {
- // Register the PowerManagement plugin with PhoneGap
- PhoneGap.addPlugin('PowerManagement', new PowerManagement());
- });
-}
+ var powermanagement = new PowerManagement();
+ module.exports = powermanagement;
+});
diff --git a/Android/PowerManagement/src/com/phonegap/plugin/PowerManagement.java b/Android/PowerManagement/src/org/apache/cordova/plugin/PowerManagement.java
similarity index 61%
rename from Android/PowerManagement/src/com/phonegap/plugin/PowerManagement.java
rename to Android/PowerManagement/src/org/apache/cordova/plugin/PowerManagement.java
index e6ab1e0..1feaebf 100644
--- a/Android/PowerManagement/src/com/phonegap/plugin/PowerManagement.java
+++ b/Android/PowerManagement/src/org/apache/cordova/plugin/PowerManagement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Wolfgang Koller
+ * Copyright (C) 2011-2012 Wolfgang Koller
*
* This file is part of GOFG Sports Computer - http://www.gofg.at/.
*
@@ -18,10 +18,10 @@
*/
/**
- * PhoneGap (Android) plugin for accessing the power-management functions of the device
+ * Cordova (Android) plugin for accessing the power-management functions of the device
* @author Wolfgang Koller
*/
-package com.phonegap.plugin;
+package org.apache.cordova.plugin;
import org.json.JSONArray;
import org.json.JSONException;
@@ -30,9 +30,10 @@ import android.content.Context;
import android.os.PowerManager;
import android.util.Log;
-import com.phonegap.api.Plugin;
-import com.phonegap.api.PluginResult;
-import com.phonegap.api.PluginResult.Status;
+import org.apache.cordova.api.CordovaInterface;
+import org.apache.cordova.api.Plugin;
+import org.apache.cordova.api.PluginResult;
+import org.apache.cordova.api.PluginResult.Status;
/**
* Plugin class which does the actual handling
@@ -40,9 +41,29 @@ import com.phonegap.api.PluginResult.Status;
public class PowerManagement extends Plugin {
// As we only allow one wake-lock, we keep a reference to it here
private PowerManager.WakeLock wakeLock = null;
+ private PowerManager powerManager = null;
+
+ /**
+ * Sets the application context for this plugin
+ * Used to obtain a reference to the powermanager
+ */
+ @Override
+ public void setContext(CordovaInterface ctx) {
+ super.setContext(ctx);
+
+ this.powerManager = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
+ }
+
+ /**
+ * We have a synchronous interface to our plugin, since all calls return immediately
+ */
+ @Override
+ public boolean isSynch(String action) {
+ return true;
+ }
/**
- * Called by the PhoneGap framework to handle a call to this plugin
+ * Called by the cordova framework to handle a call to this plugin
* @param action currently supported are 'acquire' and 'release'
* @param data In case of action 'acquire' this may contain a parameter set to 'true' to indicate only a dim wake-lock
*/
@@ -52,22 +73,22 @@ public class PowerManagement extends Plugin {
Log.d("PowerManagementPlugin", "Plugin execute called - " + this.toString() );
Log.d("PowerManagementPlugin", "Action is " + action );
- if( action.equals("acquire") ) {
- try {
- if( data.length() > 0 && data.getBoolean(0) ) {
- Log.d("PowerManagementPlugin", "Only dim lock" );
- result = this.acquire( PowerManager.SCREEN_DIM_WAKE_LOCK );
- }
- else {
- result = this.acquire( PowerManager.FULL_WAKE_LOCK );
- }
+ try {
+ if( action.equals("acquire") ) {
+ if( data.length() > 0 && data.getBoolean(0) ) {
+ Log.d("PowerManagementPlugin", "Only dim lock" );
+ result = this.acquire( PowerManager.SCREEN_DIM_WAKE_LOCK );
+ }
+ else {
+ result = this.acquire( PowerManager.FULL_WAKE_LOCK );
+ }
}
- catch( JSONException jsonEx ) {
- result = new PluginResult(Status.JSON_EXCEPTION, jsonEx.getMessage());
+ else if( action.equals("release") ) {
+ result = this.release();
}
}
- else if( action.equals("release") ) {
- result = this.release();
+ catch( JSONException e ) {
+ result = new PluginResult(Status.JSON_EXCEPTION, e.getMessage());
}
Log.d("PowerManagementPlugin", "Result is " + result.toString() );
@@ -83,15 +104,19 @@ public class PowerManagement extends Plugin {
private PluginResult acquire( int p_flags ) {
PluginResult result = null;
- if( this.wakeLock == null ) {
- PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
- this.wakeLock = pm.newWakeLock(p_flags, "PowerManagementPlugin");
- this.wakeLock.acquire();
-
- result = new PluginResult(PluginResult.Status.OK);
+ if (this.wakeLock == null) {
+ this.wakeLock = this.powerManager.newWakeLock(p_flags, "PowerManagementPlugin");
+ try {
+ this.wakeLock.acquire();
+ result = new PluginResult(PluginResult.Status.OK);
+ }
+ catch( Exception e ) {
+ this.wakeLock = null;
+ result = new PluginResult(PluginResult.Status.ERROR, "Can't acquire wake-lock - check your permissions!");
+ }
}
else {
- result = new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, "WakeLock already active - release first");
+ result = new PluginResult( PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, "WakeLock already active - release first");
}
return result;
diff --git a/Qt/PowerManagement/plugins/powermanagement.cpp b/Qt/PowerManagement/plugins/powermanagement.cpp
new file mode 100644
index 0000000..f43e52c
--- /dev/null
+++ b/Qt/PowerManagement/plugins/powermanagement.cpp
@@ -0,0 +1,31 @@
+#include "powermanagement.h"
+
+PowerManagement::PowerManagement(QWebFrame *p_webFrame) :
+ PGPlugin(p_webFrame)
+{
+ m_systemScreenSaver = new QSystemScreenSaver();
+}
+
+void PowerManagement::release( int scId, int ecId ) {
+ m_systemScreenSaver->setScreenSaverInhibited(false);
+
+ // Check if everything went fine
+ if( !m_systemScreenSaver->screenSaverInhibited() ) {
+ this->callback( scId, "" );
+ }
+ else {
+ this->callback( ecId, "" );
+ }
+}
+
+void PowerManagement::acquire( int scId, int ecId ) {
+ m_systemScreenSaver->setScreenSaverInhibited(true);
+
+ // Check if everything went fine
+ if( m_systemScreenSaver->screenSaverInhibited() ) {
+ this->callback( scId, "" );
+ }
+ else {
+ this->callback( ecId, "" );
+ }
+}
diff --git a/Qt/PowerManagement/plugins/powermanagement.h b/Qt/PowerManagement/plugins/powermanagement.h
new file mode 100644
index 0000000..3a5e5eb
--- /dev/null
+++ b/Qt/PowerManagement/plugins/powermanagement.h
@@ -0,0 +1,26 @@
+#ifndef POWERMANAGEMENT_H
+#define POWERMANAGEMENT_H
+
+#include "../pgplugin.h"
+
+#include
+
+QTM_USE_NAMESPACE
+
+class PowerManagement : public PGPlugin
+{
+ Q_OBJECT
+public:
+ explicit PowerManagement(QWebFrame *p_webFrame);
+
+signals:
+
+public slots:
+ void release( int scId, int ecId );
+ void acquire( int scId, int ecId );
+
+private:
+ QSystemScreenSaver *m_systemScreenSaver;
+};
+
+#endif // POWERMANAGEMENT_H
diff --git a/Qt/PowerManagement/www/js/powermanagement.js b/Qt/PowerManagement/www/js/powermanagement.js
new file mode 100644
index 0000000..03d1254
--- /dev/null
+++ b/Qt/PowerManagement/www/js/powermanagement.js
@@ -0,0 +1,89 @@
+/*
+ * PhoneGap is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ *
+ * Copyright (c) 2011, Wolfgang Koller - http://www.gofg.at/
+ */
+
+function PowermanagementError() {
+};
+
+PowermanagementError.cast = function( p_code, p_message ) {
+ var powerManagementError = new PowermanagementError();
+ powerManagementError.code = p_code;
+ powerManagementError.message = p_message;
+
+ return powerManagementError;
+};
+
+PowermanagementError.ALREADY_ACTIVE = 1;
+PowermanagementError.NOT_SUPPORTED = 2;
+PowermanagementError.NOT_ACTIVE = 3;
+
+PowermanagementError.prototype.code = 0;
+PowermanagementError.prototype.message = "";
+
+function Powermanagement() {
+};
+
+Powermanagement.prototype.acquired = false;
+
+Powermanagement.prototype.acquire = function( successCallback, errorCallback ) {
+ if( this.acquired ) {
+ errorCallback( PowermanagementError.cast( PowermanagementError.ALREADY_ACTIVE, "Powermanagement lock already active." ) );
+ return;
+ }
+
+ var me = this;
+ PhoneGap.exec( function() {
+ me.acquired = true;
+ successCallback();
+ }, function() {
+ me.acquired = false;
+ errorCallback( PowermanagementError.cast( PowermanagementError.NOT_SUPPORTED, "Powermanagement not supported." ) );
+ }, "com.phonegap.plugin.Powermanagement", "acquire", [] );
+};
+
+Powermanagement.prototype.release = function( successCallback, errorCallback ) {
+ if( !this.acquired ) {
+ errorCallback( PowermanagementError.cast( PowermanagementError.NOT_ACTIVE, "Powermanagement lock not active." ) );
+ return;
+ }
+
+ var me = this;
+ PhoneGap.exec( function() {
+ me.acquired = false;
+ successCallback();
+ }, function() {
+ me.acquired = false;
+ errorCallback( PowermanagementError.cast( PowermanagementError.NOT_SUPPORTED, "Powermanagement not supported." ) );
+ }, "com.phonegap.plugin.Powermanagement", "release", [] );
+};
+
+Powermanagement.prototype.dim = function( successCallback, errorCallback ) {
+ if( this.acquired ) {
+ errorCallback( PowermanagementError.cast( PowermanagementError.ALREADY_ACTIVE, "Powermanagement lock already active." ) );
+ return;
+ }
+
+ var me = this;
+ if( !PhoneGap.exec( function() {
+ me.acquired = true;
+ successCallback();
+ }, function() {
+ me.acquired = false;
+ errorCallback( PowermanagementError.cast( PowermanagementError.NOT_SUPPORTED, "Powermanagement not supported." ) );
+ }, "com.phonegap.plugin.Powermanagement", "dim", [] ) ) {
+
+ // If dimming doesn't work, try to acquire a full wake lock
+ this.acquire( successCallback, errorCallback );
+ }
+};
+
+/**
+ * Create Powermanagement instance
+ */
+PhoneGap.addConstructor( "com.phonegap.plugin.Powermanagement", function () {
+ window.Powermanagement = new Powermanagement();
+ window.PowerManagement = window.Powermanagement; // Alias for backwards compatibility
+} );