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;
}
}
}
我正在尝试在我的应用程序中实施日历事件,并且我正在关注 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;
}
}
}