具有依赖服务的Android设备日历不起作用



我制作了一个Xamarin.Forms应用程序,并希望将约会自动保存到设备日历中,恕不另行通知。

我找到了微软的解决方案:[Xamarin.Android Calendar][1]

我不知道问题是什么,我没有任何异常,程序运行良好,但我看不到任何保存到设备日历的约会。我也给了读取和写入权限

(在我也尝试过StartActivity版本之前,什么有效,但是如果我从应用程序发送30个约会,如果设备日历显示30次,用户会发疯(

请给我任何建议,有什么错?

public async Task<bool> AddAppointment(List<TestItem> xys)
{
var items = TestItem.GetAppointmentsToDeviceCalendar(xys);
foreach (CalendarEvent item in items)
{
var uri = Android.App.Application.Context.ContentResolver.Insert(CalendarContract.Events.ContentUri, ToCalendarEvent(item));
}
return true;
}
private ContentValues ToCalendarEvent(CalendarEvent item)
{
ContentValues cv = new ContentValues();
cv.Put(CalendarContract.Events.InterfaceConsts.CalendarTimeZone, TimeZone.Default.DisplayName);
cv.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, "local");
cv.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone, TimeZone.Default.DisplayName);
cv.Put(CalendarContract.Events.InterfaceConsts.CalendarId, 1);
cv.Put(CalendarContract.Events.InterfaceConsts.Title, item.Name);
cv.Put(CalendarContract.Events.InterfaceConsts.Description, item.Description);
cv.Put(CalendarContract.Events.InterfaceConsts.EventLocation, item.Location);
cv.Put(CalendarContract.Events.InterfaceConsts.Dtstart, GetDateTimeMS(item.Start.Year, item.Start.Month, item.Start.Day, item.Start.Year, item.Start.Minute));
cv.Put(CalendarContract.Events.InterfaceConsts.Dtend, GetDateTimeMS(item.End.Year, item.End.Month, item.End.Day, item.End.Hour, item.End.Minute));
return cv;
}
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, day);
c.Set(Java.Util.CalendarField.HourOfDay, hr);
c.Set(Java.Util.CalendarField.Minute, min);
c.Set(Java.Util.CalendarField.Month, month);
c.Set(Java.Util.CalendarField.Year, yr);
return c.TimeInMillis;
}
[1]: https://learn.microsoft.com/en-us/xamarin/android/user-interface/controls/calendar

若要作为同步适配器执行操作,应将CalendarContract.CALLER_IS_SYNCADAPTER设置为trueCalendarContract.SyncColumns.ACCOUNT_NAME,并且必须在Uri参数中设置CalendarContract.SyncColumns.ACCOUNT_TYPE

尝试更改代码,如下所示:

var uri = CalendarContract.Calendars.ContentUri;
uri = uri.BuildUpon()
.AppendQueryParameter(CalendarContract.CallerIsSyncadapter, "true")
.AppendQueryParameter(CalendarContract.Calendars.InterfaceConsts.AccountName, AccountName)      
.AppendQueryParameter(CalendarContract.Calendars.InterfaceConsts.AccountType, CalendarContract.AccountTypeLocal)
.Build();
Android.App.Application.Context.ContentResolver.Insert(uri, ToCalendarEvent(item));

参考: https://stackoverflow.com/a/33291608/11083277

更新:

我创建了一个基本演示来测试该功能,效果很好。该事件已添加到设备的日历中,您可以参考代码。

public class MainActivity : AppCompatActivity
{
private static string CALENDER_URL = "content://com.android.calendar/calendars";
private static string CALENDER_EVENT_URL = "content://com.android.calendar/events";
private static string CALENDER_REMINDER_URL = "content://com.android.calendar/reminders";
private static string CALENDARS_NAME = "test";
private static string CALENDARS_ACCOUNT_NAME = "test@hello.com";
private static string CALENDARS_ACCOUNT_TYPE = "com.android.test";
private static string CALENDARS_DISPLAY_NAME = "hello-test";
long account_id;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
//requestedPermission: you need request the permissions at runtime
account_id = addCalendarAccount(this);
Calendar c = Calendar.GetInstance(TimeZone.Default);
c.Set(CalendarField.DayOfMonth, 15);
c.Set(CalendarField.HourOfDay, 10);
c.Set(CalendarField.Minute, 0);
c.Set(CalendarField.Month, Calendar.July);
c.Set(CalendarField.Year, 2020);
addCalendarEvent("title", "description", c.TimeInMillis);
}
public long addCalendarAccount(Context context)
{
TimeZone timeZone = TimeZone.Default;
ContentValues value = new ContentValues();
value.Put(CalendarContract.Calendars.Name, CALENDARS_NAME);
value.Put(CalendarContract.Calendars.InterfaceConsts.AccountName, CALENDARS_ACCOUNT_NAME);
value.Put(CalendarContract.Calendars.InterfaceConsts.AccountType, CALENDARS_ACCOUNT_TYPE);
value.Put(CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName, CALENDARS_DISPLAY_NAME);
value.Put(CalendarContract.Calendars.InterfaceConsts.Visible, 1);
value.Put(CalendarContract.Calendars.InterfaceConsts.CalendarColor, Color.Blue);
value.Put(CalendarContract.Calendars.InterfaceConsts.SyncEvents, 1);
value.Put(CalendarContract.Calendars.InterfaceConsts.CalendarTimeZone, timeZone.ID);
value.Put(CalendarContract.Calendars.InterfaceConsts.OwnerAccount, CALENDARS_ACCOUNT_NAME);
Uri calendarUri = Uri.Parse(CALENDER_URL);
calendarUri = calendarUri.BuildUpon()
.AppendQueryParameter(CalendarContract.CallerIsSyncadapter, "true")
.AppendQueryParameter(CalendarContract.Calendars.InterfaceConsts.AccountName, CALENDARS_ACCOUNT_NAME)
.AppendQueryParameter(CalendarContract.Calendars.InterfaceConsts.AccountType, CALENDARS_ACCOUNT_TYPE)
.Build();
Uri result = context.ContentResolver.Insert(calendarUri, value);
long id = result == null ? -1 : ContentUris.ParseId(result);
return id;
}
public void addCalendarEvent(string title, string description, long reminderTime)
{
Calendar mCalendar = Calendar.Instance;
mCalendar.TimeInMillis = (reminderTime);//set the start time
long start = mCalendar.Time.Time;
mCalendar.TimeInMillis = (start + 10 * 60 * 1000);//set the end time
long end = mCalendar.Time.Time;
ContentValues eventValues = new ContentValues();
eventValues.Put("title", title);
eventValues.Put("description", description);
eventValues.Put("calendar_id", account_id); //int the account id
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart, start);
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend, end);
eventValues.Put(CalendarContract.Events.InterfaceConsts.HasAlarm, 1);
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, "Asia/Shanghai");
Uri newEvent = this.ContentResolver.Insert(Uri.Parse(CALENDER_EVENT_URL), eventValues);
if (newEvent == null)
{
return;
}
}
}

最新更新