2

我正在寻找一个专门与 iOS 配合使用的日历插件,尽管我也对与 Phonegap 3.0.0 兼容的 Android 插件感兴趣。我见过旧的,但据我所知,它不适用于最新版本的 Phonegap。有谁知道我在哪里可以获得适用于 Phonegap 3.0.0 的插件?

4

4 回答 4

5

如果有人仍在寻找 PhoneGap 3.0(也适用于 PhoneGap Build)的跨平台(iOS 和 Android)日历,请在此处查看:https ://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin

于 2013-10-30T08:53:50.733 回答
2

PhoneGap 插件部分有一个“官方”的 3rd 方日历插件:

https://build.phonegap.com/plugins/168

插件 ID nl.x-services.plugins.calendar

3.2 版

平台 Android、iOS

PhoneGap 版本 3.0.0、3.1.0

麻省理工学院许可证

于 2013-12-06T08:40:42.167 回答
1

嗨,我刚刚分别为 android 和 ios 构建了一个插件,我从 Felix Montanez 更改了插件,以便它与 phonegap 3.0.0 for android 一起使用

日历.js:

function CalendarPlugin() {}

CalendarPlugin.prototype.createEvent = function(title, location, notes, startDate, endDate, successCallback, errorCallback) {
    if (typeof errorCallback != "function") {
        console.log("CalendarPlugin.createEvent failure: errorCallback parameter must be a function");
        return;
    }

    if (typeof successCallback != "function") {
        console.log("CalendarPlugin.createEvent failure: successCallback parameter must be a function");
        return;
    }
    cordova.exec(successCallback, errorCallback, "CalendarPlugin", "createEvent", [title, location, notes, startDate, endDate, {
        "title": title,
        "description": notes,
        "eventLocation": location,
        "startTimeMillis": startDate.getTime(),
        "endTimeMillis": endDate.getTime()
    }]);
};

CalendarPlugin.install = function() {
    if (!window.plugins) {
        window.plugins = {};
    }

    window.plugins.CalendarPlugin = new CalendarPlugin();
    return window.plugins.CalendarPlugin;
};

cordova.addConstructor(CalendarPlugin.install);

日历插件.h

#import <Foundation/Foundation.h>
#import <Cordova/CDVPlugin.h>
#import <Cordova/CDV.h>
#import <EventKitUI/EventKitUI.h>
#import <EventKit/EventKit.h>


@interface CalendarPlugin : CDVPlugin

@property (nonatomic, retain) EKEventStore* eventStore;

- (void)initEventStoreWithCalendarCapabilities;

-(NSArray*)findEKEventsWithTitle: (NSString *)title
                        location: (NSString *)location
                         message: (NSString *)message
                       startDate: (NSDate *)startDate
                         endDate: (NSDate *)endDate;

// Calendar Instance methods

- (void)createEvent:(CDVInvokedUrlCommand*)command;
- (void)modifyEvent:(CDVInvokedUrlCommand*)command;
- (void)findEvent:(CDVInvokedUrlCommand*)command;
- (void)deleteEvent:(CDVInvokedUrlCommand*)command;

@end

日历插件.m

#import "CalendarPlugin.h"
#import <EventKitUI/EventKitUI.h>
#import <EventKit/EventKit.h>

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

@implementation CalendarPlugin
@synthesize eventStore;

#pragma mark Initialisation functions

- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView
{
    self = (CalendarPlugin*)[super initWithWebView:theWebView];
    if (self) {
        //[self setup];
        [self initEventStoreWithCalendarCapabilities];
    }
    return self;
}

- (void)initEventStoreWithCalendarCapabilities {
    __block BOOL accessGranted = NO;
    eventStore= [[EKEventStore alloc] init];
    if([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
            accessGranted = granted;
            dispatch_semaphore_signal(sema);
        }];
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    } else { // we're on iOS 5 or older
        accessGranted = YES;
    }

    if (accessGranted) {
        self.eventStore = eventStore;
    }
}

#pragma mark Helper Functions

-(NSArray*)findEKEventsWithTitle: (NSString *)title
                        location: (NSString *)location
                         message: (NSString *)message
                       startDate: (NSDate *)startDate
                         endDate: (NSDate *)endDate {

    // Build up a predicateString - this means we only query a parameter if we actually had a value in it
    NSMutableString *predicateString= [[NSMutableString alloc] initWithString:@""];
    if (title.length > 0) {
        [predicateString appendString:[NSString stringWithFormat:@"title == '%@'" , title]];
    }
    if (location.length > 0) {
        [predicateString appendString:[NSString stringWithFormat:@" AND location == '%@'" , location]];
    }
    if (message.length > 0) {
        [predicateString appendString:[NSString stringWithFormat:@" AND notes == '%@'" , message]];
    }

    NSPredicate *matches = [NSPredicate predicateWithFormat:predicateString];

    NSArray *datedEvents = [self.eventStore eventsMatchingPredicate:[eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:nil]];


    NSArray *matchingEvents = [datedEvents filteredArrayUsingPredicate:matches];


    return matchingEvents;
}

#pragma mark Cordova functions

- (void)createEvent:(CDVInvokedUrlCommand*)command {
    // Import arguments

    NSArray *arguments = command.arguments;

    NSString* title      = [arguments objectAtIndex:0];
    NSString* location   = [arguments objectAtIndex:1];
    NSString* message    = [arguments objectAtIndex:2];
    NSString *startDate  = [arguments objectAtIndex:3];
    NSString *endDate    = [arguments objectAtIndex:4];

    //creating the dateformatter object
    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *myStartDate = [df dateFromString:startDate];
    NSDate *myEndDate = [df dateFromString:endDate];


    EKEvent *myEvent = [EKEvent eventWithEventStore: self.eventStore];
    myEvent.title = title;
    myEvent.location = location;
    myEvent.notes = message;
    myEvent.startDate = myStartDate;
    myEvent.endDate = myEndDate;
    myEvent.calendar = self.eventStore.defaultCalendarForNewEvents;


    EKAlarm *reminder = [EKAlarm alarmWithRelativeOffset:-2*60*60];

    [myEvent addAlarm:reminder];

    NSError *error = nil;
    [self.eventStore saveEvent:myEvent span:EKSpanThisEvent error:&error];

    // Check error code + return result
    CDVPluginResult* pluginResult = nil;

    if (!error) {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
    } else {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
    }

    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];

}
-(void)deleteEvent:(CDVInvokedUrlCommand*)command {
    // Import arguments

    NSArray *arguments = command.arguments;

    NSString* title      = [arguments objectAtIndex:0];
    NSString* location   = [arguments objectAtIndex:1];
    NSString* message    = [arguments objectAtIndex:2];
    NSString *startDate  = [arguments objectAtIndex:3];
    NSString *endDate    = [arguments objectAtIndex:4];
    bool delAll = [arguments objectAtIndex:5];

    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *myStartDate = [df dateFromString:startDate];
    NSDate *myEndDate = [df dateFromString:endDate];

    NSArray *matchingEvents = [self findEKEventsWithTitle:title location:location message:message startDate:myStartDate endDate:myEndDate];


    if (delAll || matchingEvents.count == 1) {
        // Definitive single match - delete it!
        NSError *error = NULL;
        bool hadErrors = false;
        if (delAll) {
            for (EKEvent * event in matchingEvents) {
                [self.eventStore removeEvent:event span:EKSpanThisEvent error:&error];
                // Check for error codes and return result
                if (error) {
                    hadErrors = true;
                }
            }
        }
        else {
            [self.eventStore removeEvent:[matchingEvents lastObject] span:EKSpanThisEvent error:&error];
        }
        // Check for error codes and return result
        CDVPluginResult* pluginResult = nil;
        if (error || hadErrors) {
            NSString *messageString;
            if (hadErrors) {
                messageString = @"Error deleting events";
            }
            else {
                messageString = error.userInfo.description;
            }
                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
                                                              messageAsString:messageString];

        }
        else {
                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
        }
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
    }

}

-(void)findEvent:(CDVInvokedUrlCommand*)command {
    // Import arguments

    NSArray *arguments = command.arguments;

    NSString* title      = [arguments objectAtIndex:0];
    NSString* location   = [arguments objectAtIndex:1];
    NSString* message    = [arguments objectAtIndex:2];
    NSString *startDate  = [arguments objectAtIndex:3];
    NSString *endDate    = [arguments objectAtIndex:4];

    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *myStartDate = [df dateFromString:startDate];
    NSDate *myEndDate = [df dateFromString:endDate];

    NSArray *matchingEvents = [self findEKEventsWithTitle:title location:location message:message startDate:myStartDate endDate:myEndDate];

    NSMutableArray *finalResults = [[NSMutableArray alloc] initWithCapacity:matchingEvents.count];


    // Stringify the results - Cordova can't deal with Obj-C objects
    for (EKEvent * event in matchingEvents) {
        NSMutableDictionary *entry = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                                      event.title, @"title",
                                      event.location, @"location",
                                      event.notes, @"message",
                                      [df stringFromDate:event.startDate], @"startDate",
                                      [df stringFromDate:event.endDate], @"endDate", nil];
        [finalResults addObject:entry];
    }
    CDVPluginResult *pluginResult = nil;
    if (finalResults.count > 0) {
        // Return the results we got
        pluginResult = [CDVPluginResult
                                   resultWithStatus: CDVCommandStatus_OK
                                   messageAsArray:finalResults
                                   ];
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
    }
    else {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT];
    }
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];

}


-(void)modifyEvent:(CDVInvokedUrlCommand*)command {
    // Import arguments

    NSArray *arguments = command.arguments;

    NSString* title      = [arguments objectAtIndex:0];
    NSString* location   = [arguments objectAtIndex:1];
    NSString* message    = [arguments objectAtIndex:2];
    NSString *startDate  = [arguments objectAtIndex:3];
    NSString *endDate    = [arguments objectAtIndex:4];

    NSString* ntitle      = [arguments objectAtIndex:5];
    NSString* nlocation   = [arguments objectAtIndex:6];
    NSString* nmessage    = [arguments objectAtIndex:7];
    NSString *nstartDate  = [arguments objectAtIndex:8];
    NSString *nendDate    = [arguments objectAtIndex:9];

    // Make NSDates from our strings
    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *myStartDate = [df dateFromString:startDate];
    NSDate *myEndDate = [df dateFromString:endDate];

    // Find matches
    NSArray *matchingEvents = [self findEKEventsWithTitle:title location:location message:message startDate:myStartDate endDate:myEndDate];

    CDVPluginResult *pluginResult = nil;

    if (matchingEvents.count == 1) {
        // Presume we have to have an exact match to modify it!
        // Need to load this event from an EKEventStore so we can edit it
        EKEvent *theEvent = [self.eventStore eventWithIdentifier:((EKEvent*)[matchingEvents lastObject]).eventIdentifier];
        if (ntitle) {
            theEvent.title = ntitle;
        }
        if (nlocation) {
            theEvent.location = nlocation;
        }
        if (nmessage) {
            theEvent.notes = nmessage;
        }
        if (nstartDate) {
            NSDate *newMyStartDate = [df dateFromString:nstartDate];
            theEvent.startDate = newMyStartDate;
        }
        if (nendDate) {
            NSDate *newMyEndDate = [df dateFromString:nendDate];
            theEvent.endDate = newMyEndDate;
        }

        // Now save the new details back to the store
        NSError *error = nil;
        [self.eventStore saveEvent:theEvent span:EKSpanThisEvent error:&error];

        // Check error code + return result
        if (error) {
            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
                                                               messageAsString:error.userInfo.description];

        }
        else {
            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
        }
    }
    else {
        // Otherwise return a no result error
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT];
    }
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@end

日历插件.java

package de.drid.calendarPlugin;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;
import android.content.Intent;

public class CalendarPlugin extends CordovaPlugin {
    public static final String ACTION_ADD_CALENDAR_ENTRY = "createEvent";

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        try {
            if (ACTION_ADD_CALENDAR_ENTRY.equals(action)) { 
                JSONObject arg_object = args.getJSONObject(5);
                Intent calIntent = new Intent(Intent.ACTION_EDIT)
                    .setType("vnd.android.cursor.item/event")
                    .putExtra("beginTime", arg_object.getLong("startTimeMillis"))
                    .putExtra("endTime", arg_object.getLong("endTimeMillis"))
                    .putExtra("title", arg_object.getString("title"))
                    .putExtra("description", arg_object.getString("description"))
                    .putExtra("eventLocation", arg_object.getString("eventLocation"));

                   this.cordova.getActivity().startActivity(calIntent);
                   callbackContext.success();
                   return true;
            }
            callbackContext.error("Invalid action");
            return false;
        } catch(Exception e) {
            System.err.println("Exception: " + e.getMessage());
            callbackContext.error(e.getMessage());
            return false;
        } 
    }
}
于 2013-09-26T12:03:09.747 回答
0

这是适用于 Android 的 PhoneGap 日历插件,适用于 3.0

对于 PG 3.0,您需要修改 .java 类中的导入语句,因为它从 2.9 更改:

从此……</p>

import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;

到这个……</p>

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
于 2013-09-05T23:26:46.720 回答