本文以官方Demo的cordova-plugin-battery-status来说明。
- 定义消息
通常只是一个简单的字符串,用来方便识别。
batterystatus
2.原生端来生产事件。
private static final String LOG_TAG = "BatteryManager";
BroadcastReceiver receiver;
private CallbackContext batteryCallbackContext = null;
/**
* Constructor.
*/
public BatteryListener() {
this.receiver = null;
}
/**
* Executes the request.
*
* @param action The action to execute.
* @param args JSONArry of arguments for the plugin.
* @param callbackContext The callback context used when calling back into JavaScript.
* @return True if the action was valid, false if not.
*/
这是和js交互使用的。
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
if (action.equals("start")) {
启动时,添加一个回调。
if (this.batteryCallbackContext != null) {
removeBatteryListener();
}
this.batteryCallbackContext = callbackContext;
// 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);
}
};
webView.getContext().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);
callbackContext.sendPluginResult(pluginResult);
return true;
}
结束时移除回调
else if (action.equals("stop")) {
removeBatteryListener();
this.sendUpdate(new JSONObject(), false); // release status callback in JS side
this.batteryCallbackContext = null;
callbackContext.success();
return true;
}
return false;
}
/**
* Stop battery receiver.
*/
public void onDestroy() {
removeBatteryListener();
}
/**
* Stop battery receiver.
*/
public void onReset() {
removeBatteryListener();
}
/**
* Stop the battery receiver and set it to null.
*/
private void removeBatteryListener() {
if (this.receiver != null) {
try {
webView.getContext().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
*/
发送一个生产的事件。注意keepCallback为true,来保持连接。
private void sendUpdate(JSONObject info, boolean keepCallback) {
if (this.batteryCallbackContext != null) {
PluginResult result = new PluginResult(PluginResult.Status.OK, info);
result.setKeepCallback(keepCallback);
this.batteryCallbackContext.sendPluginResult(result);
}
}
- js端接收到这个事件,并真正把它转化成消息事件发送出去。
var cordova = require('cordova');
var exec = require('cordova/exec');
var STATUS_CRITICAL = 5;
var STATUS_LOW = 20;
var Battery = function () {
this._level = null;
this._isPlugged = null;
// Create new event handlers on the window (returns a channel instance)
this.channels = {
batterystatus: cordova.addWindowEventHandler('batterystatus'),
batterylow: cordova.addWindowEventHandler('batterylow'),
batterycritical: cordova.addWindowEventHandler('batterycritical')
};
for (var key in this.channels) {
this.channels[key].onHasSubscribersChange = Battery.onHasSubscribersChange;
}
};
function handlers () {
return battery.channels.batterystatus.numHandlers +
battery.channels.batterylow.numHandlers +
battery.channels.batterycritical.numHandlers;
}
/**
* Event handlers for when callbacks get registered for the battery.
* Keep track of how many handlers we have so we can start and stop the native battery listener
* appropriately (and hopefully save on battery life!).
*/
当有订阅时,就会调用这个方法。
Battery.onHasSubscribersChange = function () {
// If we just registered the first handler, make sure native listener is started.
订阅数目为1时启动,为0时停止。
if (this.numHandlers === 1 && handlers() === 1) {
exec(battery._status, battery._error, 'Battery', 'start', []);
} else if (handlers() === 0) {
exec(null, null, 'Battery', 'stop', []);
}
};
/**
* Callback for battery status
*
* @param {Object} info keys: level, isPlugged
*/
Battery.prototype._status = function (info) {
if (info) {
if (battery._level !== info.level || battery._isPlugged !== info.isPlugged) {
if (info.level === null && battery._level !== null) {
return; // special case where callback is called because we stopped listening to the native side.
}
// Something changed. Fire batterystatus event
cordova.fireWindowEvent('batterystatus', info);
当有事件生产时,通过cordova.fireWindowEvent来发送消息事件。
if (!info.isPlugged) { // do not fire low/critical if we are charging. issue: CB-4520
// note the following are NOT exact checks, as we want to catch a transition from
// above the threshold to below. issue: CB-4519
if (battery._level > STATUS_CRITICAL && info.level <= STATUS_CRITICAL) {
// Fire critical battery event
cordova.fireWindowEvent('batterycritical', info);
} else if (battery._level > STATUS_LOW && info.level <= STATUS_LOW) {
// Fire low battery event
cordova.fireWindowEvent('batterylow', info);
}
}
battery._level = info.level;
battery._isPlugged = info.isPlugged;
}
}
};
/**
* Error callback for battery start
*/
Battery.prototype._error = function (e) {
console.log('Error initializing Battery: ' + e);
};
var battery = new Battery(); // jshint ignore:line
module.exports = battery;
- 订阅者订阅和消费事件。
window.addEventListener("batterystatus", onBatteryStatus, false);
网友评论