datePicker 插件在 Phonegap 2.0 中不起作用
Posted
技术标签:
【中文标题】datePicker 插件在 Phonegap 2.0 中不起作用【英文标题】:datePicker plugin not working in Phonegap 2.0 【发布时间】:2012-07-31 09:23:43 【问题描述】:升级到Phonegap 2.0 后,datePicker 插件不起作用。错误是: 未捕获的类型错误:无法读取未定义的属性“datePicker”。
错误发生在 javascript 代码上: 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);
在我花时间在 google 上之后,我做了以下更改: 替换
cordova.addConstructor(function() debugger;
if (!window.plugins)
window.plugins = ;
window.plugins.datePicker = new DatePicker();
);
与
window.datePicker = new DatePicker();
更新调用它的js代码
window.datePicker.show(...
现在我仍然可以获取 datePicker 对象,但出现了这个新错误:
Uncaught TypeError: Object # has no method 'exec'
在
DatePicker.prototype.show = function(options, cb)
...
return cordova.exec(cb, failureCallback, 'DatePickerPlugin', defaults.mode, new Array(defaults));
)
感谢您的帮助!
【问题讨论】:
【参考方案1】:http://docs.phonegap.com/en/2.0.0/guide_plugin-development_android_index.md.html#Developing%20a%20Plugin%20on%20Android
检查后发现:
常见的陷阱
插件可以访问 CordovaInterface 对象。此对象有权访问运行应用程序的 Android 活动。这是启动新的 Android Intent 所需的上下文。 CordovaInterface 允许插件为结果启动 Activity,并为 Intent 返回应用程序时设置回调插件。这很重要,因为 Intents 系统是 Android 在进程之间进行通信的方式。
插件无法像过去那样直接访问上下文。旧版 ctx 成员已弃用,并将在 2.0 发布六个月后删除。 ctx 的所有方法都存在于 Context 上,因此 getContext() 和 getActivity() 都能够返回所需的正确对象。
避免使用 webView.loadUrl() 调用 JavaScript。我们有一个回调服务器的原因是为了让 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 中运行良好
【讨论】:
【参考方案2】:将输入字段设置为键入“日期”会打开本地日期选择器。超级简单的方法。
【讨论】:
【参考方案3】:window.plugins
已在 PhoneGap 2.0 中删除。尝试从https://github.com/phonegap/phonegap-plugins下载最新版本的插件。
【讨论】:
以上是关于datePicker 插件在 Phonegap 2.0 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Phonegap 2.9 在 config.xml 中声明插件
phonegap 2.2 + jQuery + Mapkit 插件