美文网首页
Cordova插件开发自定义消息事件

Cordova插件开发自定义消息事件

作者: Frank_Kivi | 来源:发表于2018-12-04 11:06 被阅读45次

本文以官方Demo的cordova-plugin-battery-status来说明。

  1. 定义消息
    通常只是一个简单的字符串,用来方便识别。
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);
        }
    }
  1. 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;
  1. 订阅者订阅和消费事件。
window.addEventListener("batterystatus", onBatteryStatus, false);

相关文章

网友评论

      本文标题:Cordova插件开发自定义消息事件

      本文链接:https://www.haomeiwen.com/subject/zutmcqtx.html