日期选择器插件中的PhoneGap 2.0不工作(datePicker plugin not wor

2019-06-26 17:33发布

升级到PhoneGap的2.0之后,日期选择器插件不起作用。 错误是:遗漏的类型错误:无法读取属性未定义的“日期选择器”。

在JavaScript代码中的错误occcurs:window.plugins.datePicker.show({...

在DatePicker的js文件:

/**
* Phonegap DatePicker Plugin Copyright (c) Greg Allen 2011 MIT Licensed
* Reused and ported to Android plugin by Daniel van 't Oever
*/
if (typeof cordova !== "undefined") {
/**
 * Constructor
 */
function DatePicker() {
    this._callback;
}

/**
 * show - true to show the ad, false to hide the ad
 */
DatePicker.prototype.show = function(options, cb) {
    if (options.date) {
        options.date = (options.date.getMonth() + 1) + "/" + (options.date.getDate()) + "/" + (options.date.getFullYear()) + "/"
                + (options.date.getHours()) + "/" + (options.date.getMinutes());
    }
    var defaults = {
        mode : '',
        date : '',
        allowOldDates : true
    };

    for ( var key in defaults) {
        if (typeof options[key] !== "undefined")
            defaults[key] = options[key];
    }
    this._callback = cb;

    return cordova.exec(cb, failureCallback, 'DatePickerPlugin', defaults.mode, new Array(defaults));
};

DatePicker.prototype._dateSelected = function(date) {
    var d = new Date(parseFloat(date) * 1000);
    if (this._callback)
        this._callback(d);
};

function failureCallback(err) {
    console.log("datePickerPlugin.js failed: " + err);
}

cordova.addConstructor(function() {debugger;
    if (!window.plugins) {
        window.plugins = {};
    }
    window.plugins.datePicker = new DatePicker();
});
};

该插件的DatePicker的Java文件:

    /**
 * 
 */
package com.phonegap.plugin;

import java.util.Calendar;
import java.util.Date;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.util.Log;
import android.widget.DatePicker;
import android.widget.TimePicker;


import org.apache.cordova.DroidGap;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;

/**
 * @author ng4e
 * @author Daniel van 't Oever
 * 
 *         Rewrote plugin so it it similar to the iOS datepicker plugin and it
 *         accepts prefilled dates and time
 */
public class DatePickerPlugin extends Plugin {

    private static final String ACTION_DATE = "date";
    private static final String ACTION_TIME = "time";
    private final String pluginName = "DatePickerPlugin";

    /*
     * (non-Javadoc)
     * 
     * @see com.phonegap.api.Plugin#execute(java.lang.String,
     * org.json.JSONArray, java.lang.String)
     */
    @Override
    public PluginResult execute(final String action, final JSONArray data, final String callBackId) {
        Log.d(pluginName, "DatePicker called with options: " + data);
        PluginResult result = null;

        this.show(data, callBackId);
        result = new PluginResult(PluginResult.Status.NO_RESULT);
        result.setKeepCallback(true);

        return result;
    }

    public synchronized void show(final JSONArray data, final String callBackId) {
        final DatePickerPlugin datePickerPlugin = this;
        @SuppressWarnings("deprecation")
        final DroidGap currentCtx = (DroidGap) ctx.getContext();
        final Calendar c = Calendar.getInstance();
        final Runnable runnable;

        String action = "date";

        /*
         * Parse information from data parameter and where possible, override
         * above date fields
         */
        int month = -1, day = -1, year = -1, hour = -1, min = -1;
        try {
            JSONObject obj = data.getJSONObject(0);
            action = obj.getString("mode");

            String optionDate = obj.getString("date");

            String[] datePart = optionDate.split("/");
            month = Integer.parseInt(datePart[0]);
            day = Integer.parseInt(datePart[1]);
            year = Integer.parseInt(datePart[2]);
            hour = Integer.parseInt(datePart[3]);
            min = Integer.parseInt(datePart[4]);

            /* currently not handled in Android */
            // boolean optionAllowOldDates = obj.getBoolean("allowOldDates");

        } catch (JSONException e) {
            e.printStackTrace();
        }

        // By default initialize these fields to 'now'
        final int mYear = year == -1 ? c.get(Calendar.YEAR) : year;
        final int mMonth = month == -1 ? c.get(Calendar.MONTH) : month - 1;
        final int mDay = day == -1 ? c.get(Calendar.DAY_OF_MONTH) : day;
        final int mHour = hour == -1 ? c.get(Calendar.HOUR_OF_DAY) : hour;
        final int mMinutes = min == -1 ? c.get(Calendar.MINUTE) : min;

        if (ACTION_TIME.equalsIgnoreCase(action)) {
            runnable = new Runnable() {
                public void run() {
                    final TimeSetListener timeSetListener = new TimeSetListener(datePickerPlugin, callBackId);
                    final TimePickerDialog timeDialog = new TimePickerDialog(currentCtx, timeSetListener, mHour,
                            mMinutes, true);
                    timeDialog.show();
                }
            };

        } else if (ACTION_DATE.equalsIgnoreCase(action)) {
            runnable = new Runnable() {
                public void run() {
                    final DateSetListener dateSetListener = new DateSetListener(datePickerPlugin, callBackId);
                    final DatePickerDialog dateDialog = new DatePickerDialog(currentCtx, dateSetListener, mYear,
                            mMonth, mDay);
                    dateDialog.show();
                }
            };

        } else {
            Log.d(pluginName, "Unknown action. Only 'date' or 'time' are valid actions");
            return;
        }

        //((Activity) ctx).runOnUiThread(runnable);
    }

    private final class DateSetListener implements OnDateSetListener {
        private final DatePickerPlugin datePickerPlugin;
        private final String callBackId;

        private DateSetListener(DatePickerPlugin datePickerPlugin, String callBackId) {
            this.datePickerPlugin = datePickerPlugin;
            this.callBackId = callBackId;
        }

        /**
         * Return a string containing the date in the format YYYY/MM/DD
         */
        public void onDateSet(final DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
            String returnDate = year + "/" + (monthOfYear + 1) + "/" + dayOfMonth;
            datePickerPlugin.success(new PluginResult(PluginResult.Status.OK, returnDate), callBackId);

        }
    }

    private final class TimeSetListener implements OnTimeSetListener {
        private final DatePickerPlugin datePickerPlugin;
        private final String callBackId;

        private TimeSetListener(DatePickerPlugin datePickerPlugin, String callBackId) {
            this.datePickerPlugin = datePickerPlugin;
            this.callBackId = callBackId;
        }

        /**
         * Return the current date with the time modified as it was set in the
         * time picker.
         */
        public void onTimeSet(final TimePicker view, final int hourOfDay, final int minute) {
            /*Date date = new Date();
            date.setHours(hourOfDay);
            date.setMinutes(minute);*/
            Calendar today = Calendar.getInstance();
            today.set(Calendar.HOUR_OF_DAY, hourOfDay);
            today.set(Calendar.MINUTE, minute);
            Date date = today.getTime();

            datePickerPlugin.success(new PluginResult(PluginResult.Status.OK, date.toString()), callBackId);

        }
    }

}

我花谷歌的时间后,我做了如下修改:更换

    cordova.addConstructor(function() {debugger;
    if (!window.plugins) {
        window.plugins = {};
    }
    window.plugins.datePicker = new DatePicker();
    });

window.datePicker = new DatePicker();

更新打电话来的js代码

window.datePicker.show({...

现在,我可以得到反正日期选择对象,但得到这个新的错误:

遗漏的类型错误:对象#有没有方法“EXEC”

DatePicker.prototype.show = function(options, cb) {
    ...
    return cordova.exec(cb, failureCallback, 'DatePickerPlugin', defaults.mode, new  Array(defaults));
})

谢谢你的帮助!

Answer 1:

http://docs.phonegap.com/en/2.0.0/guide_plugin-development_android_index.md.html#Developing%20a%20Plugin%20on%20Android

检查之后,我发现:

常见缺陷

插件有权访问CordovaInterface对象。 这个对象可以访问到正在运行的应用程序在Android活动。 这是推出新的Android意图所需的上下文。 该CordovaInterface允许使用插件来启动一个活动的结果,并设置当意图回来到应用程序回调插件。 这一点很重要,因为意图系统是Android的进程间通信如何。

插件没有上下文的直接访问,因为他们在过去。 传统CTX成员已过时,将被删除6个月2.0发布之后。 所有CTX具有存在于背景信息的方法中,因此两个的getContext()和getActivity()是能够返回所需的合适的对象。

避免调用JavaScript的使用webView.loadUrl()。 我们有一个回调服务器的原因是允许JavaScript执行是线程安全的,使用loadURL明确中断UI线程,并且会影响你的插件的可用性。

这里是我的解决办法:

在DatePickerPlugin.java

import android.content.Context;
....

public synchronized void show(final JSONArray data, final String callBackId) {
     final DatePickerPlugin datePickerPlugin = this;
     final DroidGap currentCtx = (DroidGap) ctx.getContext();
     final Calendar c = Calendar.getInstance();
.....

更换行:

final DroidGap currentCtx = (DroidGap) ctx.getContext();

通过:

final Context currentCtx = cordova.getActivity();

找:

ctx.runOnUiThread(runnable);

更换方式:

cordova.getActivity().runOnUiThread(runnable);

这是工作的罚款在我的模拟器4.0.3的PhoneGap 2.0



Answer 2:

设置输入字段中键入“日期”带来了天然的日期选择器。 超级简单的方法来做到这一点。



Answer 3:

window.plugins已PhoneGap的2.0被移除。 尝试从下载最新版本的插件https://github.com/phonegap/phonegap-plugins 。



文章来源: datePicker plugin not working in Phonegap 2.0