diff --git a/framework/assets/js/battery.js b/framework/assets/js/battery.js new file mode 100755 index 00000000..883b2de2 --- /dev/null +++ b/framework/assets/js/battery.js @@ -0,0 +1,124 @@ +/* + * 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) 2005-2010, Nitobi Software Inc. + * Copyright (c) 2010-2011, IBM Corporation + */ + +if (!PhoneGap.hasResource("battery")) { +PhoneGap.addResource("battery"); + +/** + * This class contains information about the current battery status. + * @constructor + */ +var Battery = function() { + this._level = null; + this._isPlugged = null; + this._batteryListener = []; + this._lowListener = []; + this._criticalListener = []; +}; + +/** + * Registers as an event producer for battery events. + * + * @param {Object} eventType + * @param {Object} handler + * @param {Object} add + */ +Battery.prototype.eventHandler = function(eventType, handler, add) { + var me = navigator.battery; + if (add) { + // If there are no current registered event listeners start the battery listener on native side. + if (me._batteryListener.length === 0 && me._lowListener.length === 0 && me._criticalListener.length === 0) { + PhoneGap.exec(me._status, me._error, "Battery", "start", []); + } + + // Register the event listener in the proper array + if (eventType === "batterystatus") { + var pos = me._batteryListener.indexOf(handler); + if (pos === -1) { + me._batteryListener.push(handler); + } + } else if (eventType === "batterylow") { + var pos = me._lowListener.indexOf(handler); + if (pos === -1) { + me._lowListener.push(handler); + } + } else if (eventType === "batterycritical") { + var pos = me._criticalListener.indexOf(handler); + if (pos === -1) { + me._criticalListener.push(handler); + } + } + } else { + // Remove the event listener from the proper array + if (eventType === "batterystatus") { + var pos = me._batteryListener.indexOf(handler); + if (pos > -1) { + me._batteryListener.splice(pos, 1); + } + } else if (eventType === "batterylow") { + var pos = me._lowListener.indexOf(handler); + if (pos > -1) { + me._lowListener.splice(pos, 1); + } + } else if (eventType === "batterycritical") { + var pos = me._criticalListener.indexOf(handler); + if (pos > -1) { + me._criticalListener.splice(pos, 1); + } + } + + // If there are no more registered event listeners stop the battery listener on native side. + if (me._batteryListener.length === 0 && me._lowListener.length === 0 && me._criticalListener.length === 0) { + PhoneGap.exec(null, null, "Battery", "stop", []); + } + } +}; + +/** + * Callback for battery status + * + * @param {Object} info keys: level, isPlugged + */ +Battery.prototype._status = function(info) { + if (info) { + var me = this; + if (me._level != info.level || me._isPlugged != info.isPlugged) { + // Fire batterystatus event + PhoneGap.fireWindowEvent("batterystatus", info); + + // Fire low battery event + if (info.level == 20 || info.level == 5) { + if (info.level == 20) { + PhoneGap.fireWindowEvent("batterylow", info); + } + else { + PhoneGap.fireWindowEvent("batterycritical", info); + } + } + } + me._level = info.level; + me._isPlugged = info.isPlugged; + } +}; + +/** + * Error callback for battery start + */ +Battery.prototype._error = function(e) { + console.log("Error initializing Battery: " + e); +}; + +PhoneGap.addConstructor(function() { + if (typeof navigator.battery === "undefined") { + navigator.battery = new Battery(); + PhoneGap.addWindowEventHandler("batterystatus", navigator.battery.eventHandler); + PhoneGap.addWindowEventHandler("batterylow", navigator.battery.eventHandler); + PhoneGap.addWindowEventHandler("batterycritical", navigator.battery.eventHandler); + } +}); +} diff --git a/framework/src/com/phonegap/BatteryListener.java b/framework/src/com/phonegap/BatteryListener.java new file mode 100755 index 00000000..ef939db3 --- /dev/null +++ b/framework/src/com/phonegap/BatteryListener.java @@ -0,0 +1,145 @@ +/* + * 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) 2005-2010, Nitobi Software Inc. + * Copyright (c) 2010-2011, IBM Corporation + */ +package com.phonegap; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import com.phonegap.api.Plugin; +import com.phonegap.api.PluginResult; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.util.Log; + +public class BatteryListener extends Plugin { + + private static final String LOG_TAG = "BatteryManager"; + + BroadcastReceiver receiver; + + private String batteryCallbackId = null; + + /** + * Constructor. + */ + public BatteryListener() { + this.receiver = null; + } + + /** + * Executes the request and returns PluginResult. + * + * @param action The action to execute. + * @param args JSONArry of arguments for the plugin. + * @param callbackId The callback id used when calling back into JavaScript. + * @return A PluginResult object with a status and message. + */ + public PluginResult execute(String action, JSONArray args, String callbackId) { + PluginResult.Status status = PluginResult.Status.INVALID_ACTION; + String result = "Unsupported Operation: " + action; + + if (action.equals("start")) { + if (this.batteryCallbackId != null) { + return new PluginResult(PluginResult.Status.ERROR, "Battery listener already running."); + } + this.batteryCallbackId = callbackId; + + // We need to listen to power events to update battery status + IntentFilter intentFilter = new IntentFilter() ; + intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); + if (this.receiver == null) { + this.receiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + updateBatteryInfo(intent); + } + }; + ctx.registerReceiver(this.receiver, intentFilter); + } + + // Don't return any result now, since status results will be sent when events come in from broadcast receiver + PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT); + pluginResult.setKeepCallback(true); + return pluginResult; + } + + else if (action.equals("stop")) { + removeBatteryListener(); + this.sendUpdate(new JSONObject(), false); // release status callback in JS side + this.batteryCallbackId = null; + return new PluginResult(PluginResult.Status.OK); + } + + return new PluginResult(status, result); + } + + /** + * Stop battery receiver. + */ + public void onDestroy() { + removeBatteryListener(); + } + + /** + * Stop the battery receiver and set it to null. + */ + private void removeBatteryListener() { + if (this.receiver != null) { + try { + this.ctx.unregisterReceiver(this.receiver); + this.receiver = null; + } catch (Exception e) { + Log.e(LOG_TAG, "Error unregistering battery receiver: " + e.getMessage(), e); + } + } + } + + /** + * Creates a JSONObject with the current battery information + * + * @param batteryIntent the current battery information + * @return a JSONObject containing the battery status information + */ + private JSONObject getBatteryInfo(Intent batteryIntent) { + JSONObject obj = new JSONObject(); + try { + obj.put("level", batteryIntent.getIntExtra(android.os.BatteryManager.EXTRA_LEVEL, 0)); + obj.put("isPlugged", batteryIntent.getIntExtra(android.os.BatteryManager.EXTRA_PLUGGED, -1) > 0 ? true : false); + } catch (JSONException e) { + Log.e(LOG_TAG, e.getMessage(), e); + } + return obj; + } + + /** + * Updates the JavaScript side whenever the battery changes + * + * @param batteryIntent the current battery information + * @return + */ + private void updateBatteryInfo(Intent batteryIntent) { + sendUpdate(this.getBatteryInfo(batteryIntent), true); + } + + /** + * Create a new plugin result and send it back to JavaScript + * + * @param connection the network info to set as navigator.connection + */ + private void sendUpdate(JSONObject info, boolean keepCallback) { + if (this.batteryCallbackId != null) { + PluginResult result = new PluginResult(PluginResult.Status.OK, info); + result.setKeepCallback(keepCallback); + this.success(result, this.batteryCallbackId); + } + } +}