2

Phonegap 2.0にアップグレードした後、datePickerプラグインは機能しません。エラーは次のとおりです。UncaughtTypeError:undefinedのプロパティ'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);

        }
    }

}

グーグルで時間を過ごした後、私は次の変更を加えました:置換

    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:オブジェクト#にはメソッド'exec'がありません

の上

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

助けてくれてありがとう!

4

3 に答える 3

2

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メンバーは非推奨になり、2.0がリリースされてから6か月後に削除されます。ctxがコンテキストに存在するすべてのメソッド。したがって、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);

これは、phonegap2.0を使用するエミュレーター4.0.3で正常に機能しています。

于 2012-08-03T08:44:34.233 に答える
1

入力フィールドを「date」と入力すると、ネイティブの日付ピッカーが表示されます。それを行うための超簡単な方法。

于 2013-09-20T20:42:13.683 に答える
0

window.pluginsPhoneGap2.0で削除されました。プラグインの最新バージョンをhttps://github.com/phonegap/phonegap-pluginsからダウンロードしてみてください。

于 2012-10-29T13:05:18.920 に答える