From bf3fb19a3b653f75b580d2f86ae74a089f68e893 Mon Sep 17 00:00:00 2001 From: Viras- Date: Tue, 27 Sep 2011 18:27:33 +0200 Subject: [PATCH 1/4] - Added PowerManagement plugin for Qt port of PhoneGap --- .../plugins/powermanagement.cpp | 31 +++++++ Qt/PowerManagement/plugins/powermanagement.h | 26 ++++++ Qt/PowerManagement/www/js/powermanagement.js | 89 +++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 Qt/PowerManagement/plugins/powermanagement.cpp create mode 100644 Qt/PowerManagement/plugins/powermanagement.h create mode 100644 Qt/PowerManagement/www/js/powermanagement.js 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 +} ); From f24c1c2921d4615a0aca825414dd8100d9baa9c2 Mon Sep 17 00:00:00 2001 From: Viras- Date: Tue, 3 Apr 2012 07:27:23 +0200 Subject: [PATCH 2/4] Initital version of new bluetooth plugin for cordova / phonegap --- Android/BluetoothPlugin/LICENSE | 202 +++++++++++++++ Android/BluetoothPlugin/NOTICE | 13 + .../BluetoothPlugin/assets/www/bluetooth.js | 73 ++++++ .../com/phonegap/plugin/BluetoothPlugin.java | 234 ++++++++++++++++++ 4 files changed, 522 insertions(+) create mode 100644 Android/BluetoothPlugin/LICENSE create mode 100644 Android/BluetoothPlugin/NOTICE create mode 100644 Android/BluetoothPlugin/assets/www/bluetooth.js create mode 100644 Android/BluetoothPlugin/src/com/phonegap/plugin/BluetoothPlugin.java 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/assets/www/bluetooth.js b/Android/BluetoothPlugin/assets/www/bluetooth.js new file mode 100644 index 0000000..1d815ce --- /dev/null +++ b/Android/BluetoothPlugin/assets/www/bluetooth.js @@ -0,0 +1,73 @@ +/* + 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() { + } + + /** + * 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..877c85e --- /dev/null +++ b/Android/BluetoothPlugin/src/com/phonegap/plugin/BluetoothPlugin.java @@ -0,0 +1,234 @@ +/* + 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_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 JSONArray m_discoveredDevices = null; + private JSONArray m_gotUUIDs = null; + + 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)); + + } + + @Override + public PluginResult execute(String action, JSONArray data, String callbackId) { + PluginResult pluginResult = null; + + Log.d("BluetoothPlugin", "Action: " + action); + + // Want to discover devices? + 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[1024]; + 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); + 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; + } + } + }; + +} From 9bc08b9722b3b5402a36f5f653feb347392988f2 Mon Sep 17 00:00:00 2001 From: Viras- Date: Sat, 7 Apr 2012 19:49:25 +0200 Subject: [PATCH 3/4] Adding enable / disable functionality for bluetooth --- Android/BluetoothPlugin/README.md | 37 ++++++++++ .../BluetoothPlugin/assets/www/bluetooth.js | 20 +++++ .../com/phonegap/plugin/BluetoothPlugin.java | 73 ++++++++++++++++--- 3 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 Android/BluetoothPlugin/README.md 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 index 1d815ce..0b45f81 100644 --- a/Android/BluetoothPlugin/assets/www/bluetooth.js +++ b/Android/BluetoothPlugin/assets/www/bluetooth.js @@ -23,6 +23,26 @@ if( !PhoneGap.hasResource("BluetoothPlugin") ) { 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 * diff --git a/Android/BluetoothPlugin/src/com/phonegap/plugin/BluetoothPlugin.java b/Android/BluetoothPlugin/src/com/phonegap/plugin/BluetoothPlugin.java index 877c85e..bc19972 100644 --- a/Android/BluetoothPlugin/src/com/phonegap/plugin/BluetoothPlugin.java +++ b/Android/BluetoothPlugin/src/com/phonegap/plugin/BluetoothPlugin.java @@ -41,7 +41,8 @@ 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"; @@ -54,9 +55,11 @@ public class BluetoothPlugin extends Plugin { 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(); @@ -89,6 +92,7 @@ public class BluetoothPlugin extends Plugin { 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)); } @@ -98,8 +102,40 @@ public class BluetoothPlugin extends Plugin { Log.d("BluetoothPlugin", "Action: " + action); - // Want to discover devices? - if (ACTION_DISCOVERDEVICES.equals(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()) { @@ -171,7 +207,7 @@ public class BluetoothPlugin extends Plugin { BluetoothSocket bluetoothSocket = m_bluetoothSockets.get(socketId); InputStream inputStream = bluetoothSocket.getInputStream(); - char[] buffer = new char[1024]; + char[] buffer = new char[128]; for( int i = 0; i < buffer.length; i++ ) { buffer[i] = (char) inputStream.read(); } @@ -219,14 +255,29 @@ public class BluetoothPlugin extends Plugin { m_gotUUIDs = new JSONArray(); Parcelable[] parcelUuids = intent.getParcelableArrayExtra(BluetoothPlugin.EXTRA_UUID); - 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() ); + 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; } - - m_gettingUuids = false; } } }; From f3aa90b3e71917eec4a29b7516fcf4f0de7b52aa Mon Sep 17 00:00:00 2001 From: Viras- Date: Wed, 25 Apr 2012 10:31:19 +0200 Subject: [PATCH 4/4] PowerManagement Plugin update for Cordova 1.6+ --- Android/PowerManagement/README.md | 6 +- Android/PowerManagement/assets/www/index.html | 42 ++++++++++ .../assets/www/powermanagement.js | 35 +++----- .../cordova}/plugin/PowerManagement.java | 79 ++++++++++++------- 4 files changed, 110 insertions(+), 52 deletions(-) create mode 100644 Android/PowerManagement/assets/www/index.html rename Android/PowerManagement/src/{com/phonegap => org/apache/cordova}/plugin/PowerManagement.java (61%) 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;