Xamarin Android 日历事件

Xamarin Android Calendar Events

我正在尝试在我的应用程序中实施日历事件,并且我正在关注 xamarin 网站及其日历演示中的示例,但它不起作用。我可以启动应用程序,当我按下按钮添加事件时,什么都没有 happens.Here 是我的代码,有人知道它为什么不起作用吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Provider;
using Java.Util;

namespace Bingo
{
    [Activity(Label = "EventListActivity")]
     public class EventListActivity : ListActivity
  {
    int _calId;

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);

        SetContentView (Resource.Layout.EventList);

        _calId = Intent.GetIntExtra ("calId", -1); 

        ListEvents ();

        InitAddEvent ();
    }

    void ListEvents ()
    {       
        var eventsUri = CalendarContract.Events.ContentUri;

        string[] eventsProjection = { 
            CalendarContract.Events.InterfaceConsts.Id,
            CalendarContract.Events.InterfaceConsts.Title,
            CalendarContract.Events.InterfaceConsts.Dtstart
        };

        var cursor = ManagedQuery (eventsUri, eventsProjection, 
            String.Format ("calendar_id={0}", _calId), null, "dtstart ASC");

        string[] sourceColumns = {
            CalendarContract.Events.InterfaceConsts.Title, 
            CalendarContract.Events.InterfaceConsts.Dtstart
        };

        int[] targetResources = { Resource.Id.eventTitle, Resource.Id.eventStartDate };

        var adapter = new SimpleCursorAdapter (this, Resource.Layout.EventListItem, 
            cursor, sourceColumns, targetResources); 

        adapter.ViewBinder = new ViewBinder ();

        ListAdapter = adapter;

        ListView.ItemClick += (sender, e) => { 
            int i = (e as AdapterView.ItemClickEventArgs).Position;

            cursor.MoveToPosition(i);
            int eventId = cursor.GetInt (cursor.GetColumnIndex (eventsProjection [0]));
            var uri = ContentUris.WithAppendedId(CalendarContract.Events.ContentUri, eventId);
            var intent = new Intent(Intent.ActionView, uri);
            StartActivity(intent);              
        };
    }

    void InitAddEvent ()
    {
        var addSampleEvent = FindViewById<Button> (Resource.Id.addSampleEvent);

        addSampleEvent.Click += (sender, e) => {           
            // Create Event code
            ContentValues eventValues = new ContentValues ();
            eventValues.Put (CalendarContract.Events.InterfaceConsts.CalendarId, _calId);
            eventValues.Put (CalendarContract.Events.InterfaceConsts.Title, "Test Event from M4A");
            eventValues.Put (CalendarContract.Events.InterfaceConsts.Description, "This is an event created from Mono for Android");
            eventValues.Put (CalendarContract.Events.InterfaceConsts.Dtstart, GetDateTimeMS (2015, 12, 15, 10, 0));
            eventValues.Put (CalendarContract.Events.InterfaceConsts.Dtend, GetDateTimeMS (2015, 12, 15, 11, 0));


            eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, "UTC");
            eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone, "UTC");

            var uri = ContentResolver.Insert (CalendarContract.Events.ContentUri, eventValues);
            Console.WriteLine ("Uri for new event: {0}", uri);
        };
    }

    class ViewBinder : Java.Lang.Object, SimpleCursorAdapter.IViewBinder
    {     
        public bool SetViewValue (View view, Android.Database.ICursor cursor, int columnIndex)
        {
            if (columnIndex == 2) {
                long ms = cursor.GetLong (columnIndex);

                DateTime date = 
                    new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds (ms).ToLocalTime ();

                TextView textView = (TextView)view;
                textView.Text = date.ToLongDateString ();

                return true;
            }
            return false;
        }     
    }

    long GetDateTimeMS (int yr, int month, int day, int hr, int min)
    {
        Calendar c = Calendar.GetInstance (Java.Util.TimeZone.Default);

        c.Set (Java.Util.CalendarField.DayOfMonth, 15);
        c.Set (Java.Util.CalendarField.HourOfDay, hr);
        c.Set (Java.Util.CalendarField.Minute, min);
        c.Set (Java.Util.CalendarField.Month, Calendar.December);
        c.Set (Java.Util.CalendarField.Year, 2015);

        return c.TimeInMillis;
    }

}

}

确保您在 Android 清单中设置了 READ_CALENDAR 权限。描述 here.

我遇到了同样的问题,但我解决了它,首先检查清单文件以获得所需的权限。然后,不要使用您的模拟器与日历同步,使用实际的移动设备然后尝试同步,它会完美地工作。

我知道这是一个迟到的条目,但我只是在我的 xamarin 表单应用程序上完成了这个,并且不得不拼凑所有提示和猜测来完成看似简单的任务。我的例子略有不同,因为我正在做一个依赖服务,但我认为它应该对下一个人有所帮助。

这应该会为您的用户弹出创建事件面板,让他们在点击保存之前调整标题和内容。此外,您不需要清单中的 read/write 日历权限,因为我们是从日历应用程序编写的。

这也适用于我的模拟器。 API 24

 [assembly: Dependency(typeof(CalendarAppointmentService))]
namespace Foo.Droid.Services
{
    [Activity(Label = "CalendarAppointment")]
    public class CalendarAppointmentService : ICalendarAppointmentService
    {
        private readonly static DateTime referenceDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        public CalendarAppointmentService()
        {

        }

        public async Task<bool> AddAppointment(AddAppointmentModel model)
        {
            try
            {
                Intent eventValues = new Intent(Intent.ActionInsert);
                eventValues.SetData(CalendarContract.Events.ContentUri);
                eventValues.AddFlags(ActivityFlags.NewTask);
                eventValues.PutExtra(CalendarContract.Events.InterfaceConsts.Title, model.Title);
                eventValues.PutExtra(CalendarContract.Events.InterfaceConsts.Description, model.Description);
                eventValues.PutExtra(CalendarContract.ExtraEventBeginTime, GetDateAsAndroidMS(model.StartDateTimeUTC));
                eventValues.PutExtra(CalendarContract.ExtraEventEndTime, GetDateAsAndroidMS(model.EndDateTimeUTC));
                eventValues.PutExtra(CalendarContract.Events.InterfaceConsts.EventTimezone, "UTC");
                eventValues.PutExtra(CalendarContract.Events.InterfaceConsts.EventEndTimezone, "UTC");
                eventValues.PutExtra(CalendarContract.Events.InterfaceConsts.EventLocation, model.Location);
                Android.App.Application.Context.StartActivity(eventValues);

                return await Task.FromResult(true);
            }
            catch (Exception)
            {   }
            return await Task.FromResult(false);
        }

        /// <summary>
        /// Converts a System.DateTime to an Android-expected long of milliseconds since 1970.
        /// </summary>
        /// <returns>The date as Android long value.</returns>
        /// <param name="date">Source DateTime.</param>
        public static long GetDateAsAndroidMS(DateTime date)
        {
            return (long)(date.ToUniversalTime() - referenceDate).TotalMilliseconds;
        }
    }
}