نمای کلی ارائه دهنده تقویم

ارائه دهنده تقویم یک مخزن برای رویدادهای تقویم کاربر است. API ارائه دهنده تقویم به شما امکان می دهد عملیات پرس و جو، درج، به روز رسانی و حذف را روی تقویم ها، رویدادها، شرکت کنندگان، یادآورها و غیره انجام دهید.

API ارائه‌دهنده تقویم می‌تواند توسط برنامه‌ها و آداپتورهای همگام‌سازی استفاده شود. قوانین بسته به نوع برنامه ای که تماس ها را برقرار می کند متفاوت است. این سند در درجه اول بر استفاده از API ارائه دهنده تقویم به عنوان یک برنامه متمرکز است. برای بحث در مورد تفاوت آداپتورهای همگام سازی، به آداپتورهای همگام سازی مراجعه کنید.

معمولاً برای خواندن یا نوشتن داده‌های تقویم، مانیفست برنامه باید شامل مجوزهای مناسب باشد که در مجوزهای کاربر توضیح داده شده است. برای آسان‌تر کردن انجام عملیات رایج، ارائه‌دهنده تقویم مجموعه‌ای از مقاصد را ارائه می‌کند، همانطور که در Calendar Intent توضیح داده شده است. این مقاصد کاربران را برای درج، مشاهده و ویرایش رویدادها به برنامه Calendar می برد. کاربر با برنامه Calendar تعامل می کند و سپس به برنامه اصلی باز می گردد. بنابراین برنامه شما نیازی به درخواست مجوز ندارد و همچنین نیازی به ارائه یک رابط کاربری برای مشاهده یا ایجاد رویدادها ندارد.

مبانی

ارائه‌دهندگان محتوا داده‌ها را ذخیره می‌کنند و آن‌ها را در دسترس برنامه‌ها قرار می‌دهند. ارائه دهندگان محتوای ارائه شده توسط پلت فرم اندروید (از جمله ارائه دهنده تقویم) معمولاً داده ها را به صورت مجموعه ای از جداول بر اساس مدل پایگاه داده رابطه ای نشان می دهند که در آن هر سطر یک رکورد و هر ستون داده هایی از نوع و معنای خاصی است. از طریق Calendar Provider API، برنامه‌ها و آداپتورهای همگام‌سازی می‌توانند به جداول پایگاه داده‌ای که داده‌های تقویم کاربر را در خود نگه می‌دارند، دسترسی خواندن/نوشتن داشته باشند.

هر ارائه‌دهنده محتوا یک URI عمومی (پیچیده شده به عنوان یک شی Uri ) را در معرض دید قرار می‌دهد که مجموعه داده‌های آن را به‌طور منحصربه‌فرد شناسایی می‌کند. یک ارائه‌دهنده محتوا که چندین مجموعه داده (چند جدول) را کنترل می‌کند، یک URI جداگانه برای هر یک در معرض دید قرار می‌دهد. همه URI های ارائه دهندگان با رشته "content://" شروع می شوند. این نشان می دهد که داده ها توسط یک ارائه دهنده محتوا کنترل می شوند. Calendar Provider برای هر یک از کلاس های خود (جدول) ثابت هایی را برای URI ها تعریف می کند. این URIها دارای قالب <class> .CONTENT_URI هستند. برای مثال، Events.CONTENT_URI .

شکل 1 یک نمایش گرافیکی از مدل داده ارائه دهنده تقویم را نشان می دهد. جداول اصلی و فیلدهایی را نشان می دهد که آنها را به یکدیگر مرتبط می کند.

مدل داده های ارائه دهنده تقویم

شکل 1. مدل داده های ارائه دهنده تقویم.

یک کاربر می‌تواند چندین تقویم داشته باشد و تقویم‌های مختلف را می‌توان با انواع حساب‌ها (تقویم Google، Exchange و غیره) مرتبط کرد.

CalendarContract مدل داده اطلاعات مربوط به تقویم و رویداد را تعریف می کند. این داده ها در تعدادی جداول که در زیر فهرست شده اند ذخیره می شوند.

جدول (کلاس) توضیحات

CalendarContract.Calendars

این جدول اطلاعات مربوط به تقویم را در خود دارد. هر ردیف در این جدول حاوی جزئیات مربوط به یک تقویم است، مانند نام، رنگ، اطلاعات همگام سازی و غیره.
CalendarContract.Events این جدول اطلاعات مربوط به رویداد را نگه می دارد. هر ردیف در این جدول دارای اطلاعات مربوط به یک رویداد است - به عنوان مثال، عنوان رویداد، مکان، زمان شروع، زمان پایان و غیره. این رویداد می تواند یک بار رخ دهد یا چندین بار تکرار شود. شرکت کنندگان، یادآورها، و ویژگی های توسعه یافته در جداول جداگانه ذخیره می شوند. هر کدام یک EVENT_ID دارند که به _ID در جدول رویدادها اشاره دارد.
CalendarContract.Instances این جدول زمان شروع و پایان هر رویداد یک رویداد را نشان می دهد. هر ردیف در این جدول نشان دهنده یک رخداد واحد است. برای رویدادهای یک‌باره، نگاشت 1:1 از نمونه‌ها به رویدادها وجود دارد. برای رویدادهای تکرار شونده، ردیف‌های متعددی به‌طور خودکار تولید می‌شوند که با چندین رخداد آن رویداد مطابقت دارند.
CalendarContract.Attendees این جدول اطلاعات شرکت کننده (مهمان) رویداد را نگه می دارد. هر ردیف نشان دهنده یک مهمان از یک رویداد است. نوع مهمان و پاسخ حضور مهمان برای رویداد را مشخص می کند.
CalendarContract.Reminders این جدول داده های هشدار/اعلان را نگه می دارد. هر ردیف نشان دهنده یک هشدار واحد برای یک رویداد است. یک رویداد می تواند چندین یادآور داشته باشد. حداکثر تعداد یادآورها در هر رویداد در MAX_REMINDERS مشخص شده است که توسط آداپتور همگام‌سازی که متعلق به تقویم داده شده است تنظیم می‌شود. یادآورها در چند دقیقه قبل از رویداد مشخص می شوند و روشی دارند که نحوه هشدار به کاربر را تعیین می کند.

Calendar Provider API به گونه ای طراحی شده است که انعطاف پذیر و قدرتمند باشد. در عین حال، ارائه یک تجربه کاربر نهایی خوب و محافظت از یکپارچگی تقویم و داده های آن مهم است. برای این منظور، در اینجا مواردی وجود دارد که هنگام استفاده از API باید در نظر داشته باشید:

  • درج، به روز رسانی، و مشاهده رویدادهای تقویم. برای درج مستقیم، تغییر و خواندن رویدادها از ارائه‌دهنده تقویم، به مجوزهای مناسب نیاز دارید. با این حال، اگر یک برنامه تقویم کامل یا آداپتور همگام‌سازی نمی‌سازید، درخواست این مجوزها ضروری نیست. در عوض می‌توانید از intent‌های پشتیبانی شده توسط برنامه تقویم Android برای واگذاری عملیات خواندن و نوشتن به آن برنامه استفاده کنید. هنگامی که از intent ها استفاده می کنید، برنامه شما کاربران را به برنامه Calendar می فرستد تا عملیات مورد نظر را در یک فرم از پیش پر شده انجام دهند. پس از اتمام آنها، به برنامه شما برگردانده می شوند. با طراحی برنامه خود برای انجام عملیات مشترک از طریق تقویم، یک رابط کاربری سازگار و قوی در اختیار کاربران قرار می دهید. این رویکرد توصیه شده است. برای اطلاعات بیشتر، مقاصد تقویم را ببینید.
  • همگام سازی آداپتورها یک آداپتور همگام‌سازی داده‌های تقویم موجود در دستگاه کاربر را با سرور یا منبع داده دیگری همگام‌سازی می‌کند. در جداول CalendarContract.Calendars و CalendarContract.Events ، ستون هایی وجود دارد که برای استفاده از آداپتورهای همگام سازی رزرو شده است. ارائه دهنده و برنامه ها نباید آنها را تغییر دهند. در واقع، آنها قابل مشاهده نیستند مگر اینکه به عنوان یک آداپتور همگام سازی به آنها دسترسی داشته باشید. برای اطلاعات بیشتر درباره آداپتورهای همگام‌سازی، به آداپتورهای همگام‌سازی مراجعه کنید.

مجوزهای کاربر

برای خواندن داده های تقویم، برنامه باید مجوز READ_CALENDAR را در فایل مانیفست خود داشته باشد. باید شامل مجوز WRITE_CALENDAR برای حذف، درج یا به‌روزرسانی داده‌های تقویم باشد:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"...>
    <uses-sdk android:minSdkVersion="14" />
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    ...
</manifest>

جدول تقویم

جدول CalendarContract.Calendars حاوی جزئیات برای تقویم های فردی است. ستون‌های تقویم زیر هم توسط یک برنامه کاربردی و هم توسط یک آداپتور همگام‌سازی قابل نوشتن هستند. برای فهرست کامل فیلدهای پشتیبانی شده، به مرجع CalendarContract.Calendars مراجعه کنید.

ثابت توضیحات
NAME نام تقویم.
CALENDAR_DISPLAY_NAME نام این تقویم که به کاربر نمایش داده می شود.
VISIBLE یک بولی که نشان می دهد آیا تقویم برای نمایش انتخاب شده است یا خیر. مقدار 0 نشان می دهد که رویدادهای مرتبط با این تقویم نباید نشان داده شوند. مقدار 1 نشان می دهد که رویدادهای مرتبط با این تقویم باید نشان داده شوند. این مقدار بر تولید ردیف‌ها در جدول CalendarContract.Instances تأثیر می‌گذارد.
SYNC_EVENTS یک بولی که نشان می‌دهد آیا تقویم باید همگام‌سازی شود و رویدادهای آن در دستگاه ذخیره شود. مقدار 0 می گوید این تقویم را همگام نکنید یا رویدادهای آن را در دستگاه ذخیره نکنید. مقدار 1 می گوید که رویدادها را برای این تقویم همگام کنید و رویدادهای آن را در دستگاه ذخیره کنید.

شامل یک نوع حساب برای همه عملیات

اگر در Calendars.ACCOUNT_NAME پرس و جو می کنید، باید Calendars.ACCOUNT_TYPE نیز در انتخاب قرار دهید. دلیل آن این است که یک حساب معین تنها با توجه به ACCOUNT_NAME و ACCOUNT_TYPE آن منحصر به فرد در نظر گرفته می شود. ACCOUNT_TYPE رشته متناظر با احراز هویت حساب است که هنگام ثبت حساب در AccountManager استفاده شده است. همچنین نوع خاصی از حساب به نام ACCOUNT_TYPE_LOCAL برای تقویم‌هایی که با حساب دستگاه مرتبط نیستند وجود دارد. حساب‌های ACCOUNT_TYPE_LOCAL همگام‌سازی نمی‌شوند.

پرس و جو از یک تقویم

در اینجا مثالی آورده شده است که نشان می دهد چگونه تقویم های متعلق به یک کاربر خاص را دریافت کنید. برای سادگی، در این مثال عملیات پرس و جو در رشته رابط کاربری ("رشته اصلی") نشان داده شده است. در عمل، این کار باید در یک نخ ناهمزمان به جای روی نخ اصلی انجام شود. برای بحث بیشتر، به Loaders مراجعه کنید. اگر فقط داده‌ها را نمی‌خوانید، بلکه آن‌ها را اصلاح می‌کنید، به AsyncQueryHandler مراجعه کنید.

کاتلین

// Projection array. Creating indices for this array instead of doing
// dynamic lookups improves performance.
private val EVENT_PROJECTION: Array<String> = arrayOf(
        CalendarContract.Calendars._ID,                     // 0
        CalendarContract.Calendars.ACCOUNT_NAME,            // 1
        CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,   // 2
        CalendarContract.Calendars.OWNER_ACCOUNT            // 3
)

// The indices for the projection array above.
private const val PROJECTION_ID_INDEX: Int = 0
private const val PROJECTION_ACCOUNT_NAME_INDEX: Int = 1
private const val PROJECTION_DISPLAY_NAME_INDEX: Int = 2
private const val PROJECTION_OWNER_ACCOUNT_INDEX: Int = 3

جاوا

// Projection array. Creating indices for this array instead of doing
// dynamic lookups improves performance.
public static final String[] EVENT_PROJECTION = new String[] {
    Calendars._ID,                           // 0
    Calendars.ACCOUNT_NAME,                  // 1
    Calendars.CALENDAR_DISPLAY_NAME,         // 2
    Calendars.OWNER_ACCOUNT                  // 3
};

// The indices for the projection array above.
private static final int PROJECTION_ID_INDEX = 0;
private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;

در قسمت بعدی مثال، پرس و جو خود را می سازید. انتخاب معیارهای پرس و جو را مشخص می کند. در این مثال، پرس و جو به دنبال تقویم هایی است که دارای ACCOUNT_NAME "hera@example.com"، ACCOUNT_TYPE "com.example" و OWNER_ACCOUNT "hera@example.com" هستند. اگر می‌خواهید همه تقویم‌هایی را که کاربر مشاهده کرده است ببینید، نه فقط تقویم‌هایی که کاربر دارد، OWNER_ACCOUNT را حذف کنید. کوئری یک شی Cursor را برمی گرداند که می توانید از آن برای عبور از مجموعه نتایجی که توسط کوئری پایگاه داده بازگردانده شده است استفاده کنید. برای بحث بیشتر در مورد استفاده از پرس و جو در ارائه دهندگان محتوا، به ارائه دهندگان محتوا مراجعه کنید.

کاتلین

// Run query
val uri: Uri = CalendarContract.Calendars.CONTENT_URI
val selection: String = "((${CalendarContract.Calendars.ACCOUNT_NAME} = ?) AND (" +
        "${CalendarContract.Calendars.ACCOUNT_TYPE} = ?) AND (" +
        "${CalendarContract.Calendars.OWNER_ACCOUNT} = ?))"
val selectionArgs: Array<String> = arrayOf("hera@example.com", "com.example", "hera@example.com")
val cur: Cursor = contentResolver.query(uri, EVENT_PROJECTION, selection, selectionArgs, null)

جاوا

// Run query
Cursor cur = null;
ContentResolver cr = getContentResolver();
Uri uri = Calendars.CONTENT_URI;
String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND ("
                        + Calendars.ACCOUNT_TYPE + " = ?) AND ("
                        + Calendars.OWNER_ACCOUNT + " = ?))";
String[] selectionArgs = new String[] {"hera@example.com", "com.example",
        "hera@example.com"};
// Submit the query and get a Cursor object back.
cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);

این بخش بعدی از مکان نما برای گذر از مجموعه نتایج استفاده می کند. از ثابت‌هایی که در ابتدای مثال تنظیم شده‌اند برای برگرداندن مقادیر هر فیلد استفاده می‌کند.

کاتلین

// Use the cursor to step through the returned records
while (cur.moveToNext()) {
    // Get the field values
    val calID: Long = cur.getLong(PROJECTION_ID_INDEX)
    val displayName: String = cur.getString(PROJECTION_DISPLAY_NAME_INDEX)
    val accountName: String = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX)
    val ownerName: String = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX)
    // Do something with the values...
}

جاوا

// Use the cursor to step through the returned records
while (cur.moveToNext()) {
    long calID = 0;
    String displayName = null;
    String accountName = null;
    String ownerName = null;

    // Get the field values
    calID = cur.getLong(PROJECTION_ID_INDEX);
    displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
    accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
    ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);

    // Do something with the values...

   ...
}

یک تقویم را اصلاح کنید

برای انجام به‌روزرسانی یک تقویم، می‌توانید _ID تقویم را به عنوان شناسه پیوست شده به Uri ( withAppendedId() ) یا به عنوان اولین آیتم انتخابی ارائه کنید. انتخاب باید با "_id=?" شروع شود. و اولین selectionArg باید _ID تقویم باشد. همچنین می‌توانید با رمزگذاری شناسه در URI به‌روزرسانی‌ها را انجام دهید. این مثال نام نمایشی تقویم را با استفاده از رویکرد ( withAppendedId() ) تغییر می دهد:

کاتلین

const val DEBUG_TAG: String = "MyActivity"
...
val calID: Long = 2
val values = ContentValues().apply {
    // The new display name for the calendar
    put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar")
}
val updateUri: Uri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, calID)
val rows: Int = contentResolver.update(updateUri, values, null, null)
Log.i(DEBUG_TAG, "Rows updated: $rows")

جاوا

private static final String DEBUG_TAG = "MyActivity";
...
long calID = 2;
ContentValues values = new ContentValues();
// The new display name for the calendar
values.put(Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar");
Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID);
int rows = getContentResolver().update(updateUri, values, null, null);
Log.i(DEBUG_TAG, "Rows updated: " + rows);

درج یک تقویم

تقویم‌ها عمدتاً توسط یک آداپتور همگام‌سازی مدیریت می‌شوند، بنابراین شما فقط باید تقویم‌های جدید را به عنوان آداپتور همگام‌سازی درج کنید. در بیشتر موارد، برنامه‌ها فقط می‌توانند تغییرات سطحی در تقویم‌ها ایجاد کنند، مانند تغییر نام نمایشی. اگر برنامه‌ای نیاز به ایجاد یک تقویم محلی دارد، می‌تواند این کار را با انجام درج تقویم به عنوان یک آداپتور همگام‌سازی، با استفاده از ACCOUNT_TYPE از ACCOUNT_TYPE_LOCAL انجام دهد. ACCOUNT_TYPE_LOCAL یک نوع حساب ویژه برای تقویم‌هایی است که با حساب دستگاه مرتبط نیستند. تقویم‌های این نوع با سرور همگام‌سازی نمی‌شوند. برای بحث در مورد آداپتورهای همگام سازی، به آداپتورهای همگام سازی مراجعه کنید.

جدول رویدادها

جدول CalendarContract.Events حاوی جزئیات رویدادهای فردی است. برای افزودن، به‌روزرسانی یا حذف رویدادها، برنامه باید مجوز WRITE_CALENDAR را در فایل مانیفست خود داشته باشد.

ستون‌های رویدادهای زیر هم توسط یک برنامه کاربردی و هم توسط یک آداپتور همگام‌سازی قابل نوشتن هستند. برای فهرست کامل فیلدهای پشتیبانی شده، به مرجع CalendarContract.Events مراجعه کنید.

ثابت توضیحات
CALENDAR_ID _ID تقویمی که رویداد به آن تعلق دارد.
ORGANIZER ایمیل برگزارکننده (صاحب) رویداد.
TITLE عنوان رویداد.
EVENT_LOCATION جایی که رویداد رخ می دهد.
DESCRIPTION شرح واقعه.
DTSTART زمان شروع رویداد بر حسب میلی ثانیه UTC از آن دوره.
DTEND زمان پایان رویداد بر حسب میلی ثانیه UTC از آن دوره.
EVENT_TIMEZONE منطقه زمانی رویداد
EVENT_END_TIMEZONE منطقه زمانی برای زمان پایان رویداد.
DURATION مدت زمان رویداد در قالب RFC5545 . به عنوان مثال، مقدار "PT1H" بیان می کند که رویداد باید یک ساعت طول بکشد و مقدار "P2W" نشان دهنده مدت زمان 2 هفته است.
ALL_DAY مقدار 1 نشان می دهد که این رویداد کل روز را اشغال می کند، همانطور که توسط منطقه زمانی محلی تعریف شده است. مقدار 0 نشان می دهد که یک رویداد عادی است که ممکن است در هر زمانی در طول روز شروع و پایان یابد.
RRULE قانون تکرار برای قالب رویداد. به عنوان مثال، "FREQ=WEEKLY;COUNT=10;WKST=SU" . می توانید نمونه های بیشتری را در اینجا بیابید.
RDATE تاریخ های تکرار رویداد شما معمولاً RDATE در ارتباط با RRULE برای تعریف مجموعه ای از تکرارهای تکراری استفاده می کنید. برای بحث بیشتر، مشخصات RFC5545 را ببینید.
AVAILABILITY اگر این رویداد به عنوان زمان شلوغ به حساب می آید یا زمان آزاد است که می توان آن را به پایان رساند.
GUESTS_CAN_MODIFY آیا مهمانان می توانند رویداد را تغییر دهند یا خیر.
GUESTS_CAN_INVITE_OTHERS آیا مهمانان می توانند مهمانان دیگر را دعوت کنند یا خیر.
GUESTS_CAN_SEE_GUESTS آیا مهمانان می توانند لیست شرکت کنندگان را ببینند یا خیر.

رویدادها را اضافه کنید

هنگامی که برنامه شما رویداد جدیدی را درج می کند، توصیه می کنیم از INSERT Intent استفاده کنید، همانطور که در استفاده از یک intent برای درج رویداد توضیح داده شده است. با این حال، در صورت نیاز، می توانید رویدادها را مستقیماً درج کنید. در این بخش نحوه انجام این کار توضیح داده شده است.

در اینجا قوانین درج یک رویداد جدید وجود دارد:

  • باید CALENDAR_ID و DTSTART را وارد کنید.
  • باید یک EVENT_TIMEZONE اضافه کنید. برای دریافت لیستی از شناسه های منطقه زمانی نصب شده سیستم، از getAvailableIDs() استفاده کنید. توجه داشته باشید که اگر رویدادی را از طریق INSERT Intent درج می‌کنید که در استفاده از intent برای درج رویداد توضیح داده شده است، این قانون اعمال نمی‌شود - در آن سناریو، یک منطقه زمانی پیش‌فرض ارائه می‌شود.
  • برای رویدادهای غیر تکراری، باید DTEND اضافه کنید.
  • برای رویدادهای تکرار شونده، باید یک DURATION علاوه بر RRULE یا RDATE اضافه کنید. توجه داشته باشید که اگر رویدادی را از طریق INSERT Intent درج می‌کنید، که در استفاده از intent برای درج رویداد توضیح داده شده است، این قانون اعمال نمی‌شود — در آن سناریو، می‌توانید از RRULE در ارتباط با DTSTART و DTEND استفاده کنید و برنامه Calendar تبدیل می‌کند. آن را به یک مدت به طور خودکار.

در اینجا نمونه ای از درج یک رویداد است. این برای سادگی در رشته UI انجام می شود. در عمل، درج و به روز رسانی باید در یک رشته ناهمزمان انجام شود تا عمل به یک رشته پس زمینه منتقل شود. برای اطلاعات بیشتر، AsyncQueryHandler ببینید.

کاتلین

val calID: Long = 3
val startMillis: Long = Calendar.getInstance().run {
    set(2012, 9, 14, 7, 30)
    timeInMillis
}
val endMillis: Long = Calendar.getInstance().run {
    set(2012, 9, 14, 8, 45)
    timeInMillis
}
...

val values = ContentValues().apply {
    put(CalendarContract.Events.DTSTART, startMillis)
    put(CalendarContract.Events.DTEND, endMillis)
    put(CalendarContract.Events.TITLE, "Jazzercise")
    put(CalendarContract.Events.DESCRIPTION, "Group workout")
    put(CalendarContract.Events.CALENDAR_ID, calID)
    put(CalendarContract.Events.EVENT_TIMEZONE, "America/Los_Angeles")
}
val uri: Uri = contentResolver.insert(CalendarContract.Events.CONTENT_URI, values)

// get the event ID that is the last element in the Uri
val eventID: Long = uri.lastPathSegment.toLong()
//
// ... do something with event ID
//
//

جاوا

long calID = 3;
long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 9, 14, 7, 30);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 9, 14, 8, 45);
endMillis = endTime.getTimeInMillis();
...

ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Events.DTSTART, startMillis);
values.put(Events.DTEND, endMillis);
values.put(Events.TITLE, "Jazzercise");
values.put(Events.DESCRIPTION, "Group workout");
values.put(Events.CALENDAR_ID, calID);
values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles");
Uri uri = cr.insert(Events.CONTENT_URI, values);

// get the event ID that is the last element in the Uri
long eventID = Long.parseLong(uri.getLastPathSegment());
//
// ... do something with event ID
//
//

توجه: ببینید این مثال چگونه شناسه رویداد را پس از ایجاد رویداد ثبت می کند. این ساده ترین راه برای دریافت شناسه رویداد است. شما اغلب برای انجام سایر عملیات تقویم به شناسه رویداد نیاز دارید - به عنوان مثال، برای افزودن شرکت کنندگان یا یادآوری به یک رویداد.

رویدادها را به روز کنید

وقتی برنامه شما می‌خواهد به کاربر اجازه ویرایش یک رویداد را بدهد، توصیه می‌کنیم از EDIT Intent استفاده کنید، همانطور که در استفاده از intent برای ویرایش یک رویداد توضیح داده شده است. با این حال، در صورت نیاز، می توانید رویدادها را مستقیماً ویرایش کنید. برای انجام به‌روزرسانی یک رویداد، می‌توانید _ID رویداد را یا به‌عنوان شناسه پیوست شده به Uri ( withAppendedId() ) یا به‌عنوان اولین مورد انتخابی ارائه کنید. انتخاب باید با "_id=?" شروع شود. ، و اولین selectionArg باید _ID رویداد باشد. همچنین می‌توانید با استفاده از انتخابی بدون شناسه، به‌روزرسانی‌ها را انجام دهید. در اینجا نمونه ای از به روز رسانی یک رویداد است. عنوان رویداد را با استفاده از رویکرد withAppendedId() تغییر می دهد:

کاتلین

val DEBUG_TAG = "MyActivity"
...
val eventID: Long = 188
...
val values = ContentValues().apply {
    // The new title for the event
    put(CalendarContract.Events.TITLE, "Kickboxing")
}
val updateUri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID)
val rows: Int = contentResolver.update(updateUri, values, null, null)
Log.i(DEBUG_TAG, "Rows updated: $rows")

جاوا

private static final String DEBUG_TAG = "MyActivity";
...
long eventID = 188;
...
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
Uri updateUri = null;
// The new title for the event
values.put(Events.TITLE, "Kickboxing");
updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
int rows = cr.update(updateUri, values, null, null);
Log.i(DEBUG_TAG, "Rows updated: " + rows);

حذف رویدادها

شما می توانید یک رویداد را با _ID آن به عنوان شناسه ضمیمه شده در URI یا با استفاده از انتخاب استاندارد حذف کنید. اگر از شناسه ضمیمه شده استفاده می کنید، نمی توانید انتخابی نیز انجام دهید. دو نسخه حذف وجود دارد: به عنوان یک برنامه و به عنوان یک آداپتور همگام. یک برنامه حذف، ستون حذف شده را روی 1 تنظیم می کند. این پرچم به آداپتور همگام سازی می گوید که ردیف حذف شده است و این حذف باید به سرور منتشر شود. حذف آداپتور همگام‌سازی رویداد را به همراه تمام داده‌های مرتبط با آن از پایگاه داده حذف می‌کند. در اینجا یک مثال از برنامه حذف یک رویداد از طریق _ID آن است:

کاتلین

val DEBUG_TAG = "MyActivity"
...
val eventID: Long = 201
...
val deleteUri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID)
val rows: Int = contentResolver.delete(deleteUri, null, null)
Log.i(DEBUG_TAG, "Rows deleted: $rows")

جاوا

private static final String DEBUG_TAG = "MyActivity";
...
long eventID = 201;
...
ContentResolver cr = getContentResolver();
Uri deleteUri = null;
deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
int rows = cr.delete(deleteUri, null, null);
Log.i(DEBUG_TAG, "Rows deleted: " + rows);

میز شرکت کنندگان

هر ردیف از جدول CalendarContract.Attendees نشان دهنده یک شرکت کننده یا مهمان در یک رویداد است. فراخوانی query() لیستی از شرکت کنندگان را برای رویداد با EVENT_ID داده شده برمی گرداند. این EVENT_ID باید با _ID یک رویداد خاص مطابقت داشته باشد.

جدول زیر فیلدهای قابل نوشتن را فهرست می کند. هنگام وارد کردن یک شرکت‌کننده جدید، باید همه آنها را به‌جز ATTENDEE_NAME وارد کنید.

ثابت توضیحات
EVENT_ID شناسه رویداد.
ATTENDEE_NAME نام شرکت کننده.
ATTENDEE_EMAIL آدرس ایمیل شرکت کننده.
ATTENDEE_RELATIONSHIP

رابطه شرکت کنندگان با رویداد. یکی از:

ATTENDEE_TYPE

نوع شرکت کننده یکی از:

ATTENDEE_STATUS

وضعیت حضور شرکت کننده. یکی از:

شرکت کنندگان را اضافه کنید

در اینجا یک مثال است که یک شرکت کننده مجرد را به یک رویداد اضافه می کند. توجه داشته باشید که EVENT_ID مورد نیاز است:

کاتلین

val eventID: Long = 202
...
val values = ContentValues().apply {
    put(CalendarContract.Attendees.ATTENDEE_NAME, "Trevor")
    put(CalendarContract.Attendees.ATTENDEE_EMAIL, "trevor@example.com")
    put(
        CalendarContract.Attendees.ATTENDEE_RELATIONSHIP,
        CalendarContract.Attendees.RELATIONSHIP_ATTENDEE
    )
    put(CalendarContract.Attendees.ATTENDEE_TYPE, CalendarContract.Attendees.TYPE_OPTIONAL)
    put(
        CalendarContract.Attendees.ATTENDEE_STATUS,
        CalendarContract.Attendees.ATTENDEE_STATUS_INVITED
    )
    put(CalendarContract.Attendees.EVENT_ID, eventID)
}
val uri: Uri = contentResolver.insert(CalendarContract.Attendees.CONTENT_URI, values)

جاوا

long eventID = 202;
...
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Attendees.ATTENDEE_NAME, "Trevor");
values.put(Attendees.ATTENDEE_EMAIL, "trevor@example.com");
values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL);
values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
values.put(Attendees.EVENT_ID, eventID);
Uri uri = cr.insert(Attendees.CONTENT_URI, values);

جدول یادآوری ها

هر ردیف از جدول CalendarContract.Reminders نشان دهنده یک یادآوری واحد برای یک رویداد است. فراخوانی query() لیستی از یادآورها را برای رویداد با EVENT_ID داده شده برمی گرداند.

جدول زیر فیلدهای قابل نوشتن را برای یادآوری فهرست می کند. همه آنها باید هنگام درج یادآوری جدید درج شوند. توجه داشته باشید که آداپتورهای همگام‌سازی انواع یادآوری‌هایی را که پشتیبانی می‌کنند در جدول CalendarContract.Calendars مشخص می‌کنند. برای جزئیات به ALLOWED_REMINDERS مراجعه کنید.

ثابت توضیحات
EVENT_ID شناسه رویداد.
MINUTES دقایقی قبل از رویداد که یادآوری باید فعال شود.
METHOD

روش هشدار، همانطور که در سرور تنظیم شده است. یکی از:

یادآوری ها را اضافه کنید

این مثال یک یادآوری به یک رویداد اضافه می کند. یادآور 15 دقیقه قبل از رویداد پخش می شود.

کاتلین

val eventID: Long = 221
...
val values = ContentValues().apply {
    put(CalendarContract.Reminders.MINUTES, 15)
    put(CalendarContract.Reminders.EVENT_ID, eventID)
    put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT)
}
val uri: Uri = contentResolver.insert(CalendarContract.Reminders.CONTENT_URI, values)

جاوا

long eventID = 221;
...
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Reminders.MINUTES, 15);
values.put(Reminders.EVENT_ID, eventID);
values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
Uri uri = cr.insert(Reminders.CONTENT_URI, values);

جدول نمونه ها

جدول CalendarContract.Instances زمان شروع و پایان را برای وقوع یک رویداد نگه می دارد. هر ردیف در این جدول نشان دهنده یک رخداد واحد است. جدول نمونه ها قابل نوشتن نیست و فقط راهی برای پرس و جو از رخدادهای رویداد ارائه می دهد.

جدول زیر برخی از فیلدهایی را که می توانید برای نمونه در آنها پرس و جو کنید فهرست می کند. توجه داشته باشید که منطقه زمانی توسط KEY_TIMEZONE_TYPE و KEY_TIMEZONE_INSTANCES تعریف می‌شود.

ثابت توضیحات
BEGIN زمان شروع نمونه، در UTC میلی ثانیه.
END زمان پایان نمونه، در UTC میلی ثانیه.
END_DAY روز پایان جولیان نمونه، نسبت به منطقه زمانی تقویم.
END_MINUTE دقیقه پایانی نمونه از نیمه شب در منطقه زمانی تقویم اندازه‌گیری می‌شود.
EVENT_ID _ID رویداد برای این مثال.
START_DAY روز شروع جولیان نمونه، نسبت به منطقه زمانی تقویم.
START_MINUTE دقیقه شروع نمونه از نیمه شب، نسبت به منطقه زمانی تقویم اندازه گیری می شود.

جدول نمونه ها را پرس و جو کنید

برای پرس و جو از جدول Instances، باید یک بازه زمانی برای پرس و جو در URI مشخص کنید. در این مثال، CalendarContract.Instances از طریق اجرای واسط CalendarContract.EventsColumns به فیلد TITLE دسترسی پیدا می کند. به عبارت دیگر، TITLE از طریق نمای پایگاه داده برگردانده می شود، نه از طریق پرس و جو در جدول خام CalendarContract.Instances .

کاتلین

const val DEBUG_TAG: String = "MyActivity"
val INSTANCE_PROJECTION: Array<String> = arrayOf(
        CalendarContract.Instances.EVENT_ID, // 0
        CalendarContract.Instances.BEGIN, // 1
        CalendarContract.Instances.TITLE // 2
)

// The indices for the projection array above.
const val PROJECTION_ID_INDEX: Int = 0
const val PROJECTION_BEGIN_INDEX: Int = 1
const val PROJECTION_TITLE_INDEX: Int = 2

// Specify the date range you want to search for recurring
// event instances
val startMillis: Long = Calendar.getInstance().run {
    set(2011, 9, 23, 8, 0)
    timeInMillis
}
val endMillis: Long = Calendar.getInstance().run {
    set(2011, 10, 24, 8, 0)
    timeInMillis
}

// The ID of the recurring event whose instances you are searching
// for in the Instances table
val selection: String = "${CalendarContract.Instances.EVENT_ID} = ?"
val selectionArgs: Array<String> = arrayOf("207")

// Construct the query with the desired date range.
val builder: Uri.Builder = CalendarContract.Instances.CONTENT_URI.buildUpon()
ContentUris.appendId(builder, startMillis)
ContentUris.appendId(builder, endMillis)

// Submit the query
val cur: Cursor = contentResolver.query(
        builder.build(),
        INSTANCE_PROJECTION,
        selection,
        selectionArgs, null
)
while (cur.moveToNext()) {
    // Get the field values
    val eventID: Long = cur.getLong(PROJECTION_ID_INDEX)
    val beginVal: Long = cur.getLong(PROJECTION_BEGIN_INDEX)
    val title: String = cur.getString(PROJECTION_TITLE_INDEX)

    // Do something with the values.
    Log.i(DEBUG_TAG, "Event: $title")
    val calendar = Calendar.getInstance().apply {
        timeInMillis = beginVal
    }
    val formatter = SimpleDateFormat("MM/dd/yyyy")
    Log.i(DEBUG_TAG, "Date: ${formatter.format(calendar.time)}")
}

جاوا

private static final String DEBUG_TAG = "MyActivity";
public static final String[] INSTANCE_PROJECTION = new String[] {
    Instances.EVENT_ID,      // 0
    Instances.BEGIN,         // 1
    Instances.TITLE          // 2
  };

// The indices for the projection array above.
private static final int PROJECTION_ID_INDEX = 0;
private static final int PROJECTION_BEGIN_INDEX = 1;
private static final int PROJECTION_TITLE_INDEX = 2;
...

// Specify the date range you want to search for recurring
// event instances
Calendar beginTime = Calendar.getInstance();
beginTime.set(2011, 9, 23, 8, 0);
long startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2011, 10, 24, 8, 0);
long endMillis = endTime.getTimeInMillis();

Cursor cur = null;
ContentResolver cr = getContentResolver();

// The ID of the recurring event whose instances you are searching
// for in the Instances table
String selection = Instances.EVENT_ID + " = ?";
String[] selectionArgs = new String[] {"207"};

// Construct the query with the desired date range.
Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, startMillis);
ContentUris.appendId(builder, endMillis);

// Submit the query
cur =  cr.query(builder.build(),
    INSTANCE_PROJECTION,
    selection,
    selectionArgs,
    null);

while (cur.moveToNext()) {
    String title = null;
    long eventID = 0;
    long beginVal = 0;

    // Get the field values
    eventID = cur.getLong(PROJECTION_ID_INDEX);
    beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
    title = cur.getString(PROJECTION_TITLE_INDEX);

    // Do something with the values.
    Log.i(DEBUG_TAG, "Event:  " + title);
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(beginVal);
    DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
    Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime()));
    }
 }

مقاصد تقویم

برنامه شما برای خواندن و نوشتن داده های تقویم نیازی به مجوز ندارد. در عوض می‌تواند از هدف‌های پشتیبانی شده توسط برنامه تقویم اندروید برای واگذاری عملیات خواندن و نوشتن به آن برنامه استفاده کند. جدول زیر اهداف پشتیبانی شده توسط Calendar Provider را فهرست می کند:

اقدام URI توضیحات موارد اضافی

VIEW

content://com.android.calendar/time/<ms_since_epoch>

همچنین می توانید با CalendarContract.CONTENT_URI به URI مراجعه کنید. برای مثالی از استفاده از این intent، به استفاده از intent برای مشاهده داده های تقویم مراجعه کنید.
تقویم را به زمان مشخص شده توسط <ms_since_epoch> باز کنید. هیچ کدام

VIEW

content://com.android.calendar/events/<event_id>

همچنین می‌توانید با Events.CONTENT_URI به URI مراجعه کنید.CONTENT_URI. برای مثالی از استفاده از این intent، به استفاده از intent برای مشاهده داده های تقویم مراجعه کنید.
رویداد مشخص شده توسط <event_id> را مشاهده کنید. CalendarContract.EXTRA_EVENT_BEGIN_TIME


CalendarContract.EXTRA_EVENT_END_TIME
EDIT

content://com.android.calendar/events/<event_id>

همچنین می‌توانید با Events.CONTENT_URI به URI مراجعه کنید.CONTENT_URI. برای مثالی از استفاده از این intent، به استفاده از intent برای ویرایش یک رویداد مراجعه کنید.
رویداد مشخص شده توسط <event_id> را ویرایش کنید. CalendarContract.EXTRA_EVENT_BEGIN_TIME


CalendarContract.EXTRA_EVENT_END_TIME
EDIT

INSERT

content://com.android.calendar/events

همچنین می‌توانید با Events.CONTENT_URI به URI مراجعه کنید.CONTENT_URI. برای مثالی از استفاده از این intent، به استفاده از intent برای درج یک رویداد مراجعه کنید.
یک رویداد ایجاد کنید. هر یک از موارد اضافی ذکر شده در جدول زیر.

جدول زیر موارد اضافی قصد پشتیبانی شده توسط Calendar Provider را فهرست می کند:

قصد اضافی توضیحات
Events.TITLE نام رویداد
CalendarContract.EXTRA_EVENT_BEGIN_TIME زمان شروع رویداد بر حسب میلی ثانیه از آن دوره است.
CalendarContract.EXTRA_EVENT_END_TIME زمان پایان رویداد در میلی ثانیه از دوران.
CalendarContract.EXTRA_EVENT_ALL_DAY یک بولی که نشان می دهد یک رویداد تمام روز است. مقدار می تواند true یا false باشد.
Events.EVENT_LOCATION محل برگزاری.
Events.DESCRIPTION شرح رویداد.
Intent.EXTRA_EMAIL آدرس ایمیل کسانی که باید به عنوان یک لیست جدا شده با کاما دعوت شوند.
Events.RRULE قانون تکرار برای رویداد.
Events.ACCESS_LEVEL خواه این رویداد خصوصی باشد یا عمومی.
Events.AVAILABILITY اگر این رویداد به عنوان زمان شلوغ به حساب می آید یا زمان آزاد است که می توان آن را به پایان رساند.

بخش‌های زیر نحوه استفاده از این مقاصد را توضیح می‌دهند.

از یک intent برای درج یک رویداد استفاده کنید

استفاده از INSERT Intent به برنامه شما اجازه می دهد تا وظیفه درج رویداد را به خود تقویم واگذار کند. با این رویکرد، برنامه شما حتی نیازی به داشتن مجوز WRITE_CALENDAR در فایل مانیفست خود ندارد.

وقتی کاربران برنامه‌ای را اجرا می‌کنند که از این رویکرد استفاده می‌کند، برنامه آن‌ها را به تقویم ارسال می‌کند تا افزودن رویداد را تمام کند. INSERT Intent از فیلدهای اضافی برای پر کردن فرم از قبل با جزئیات رویداد در تقویم استفاده می کند. سپس کاربران می توانند رویداد را لغو کنند، فرم را در صورت نیاز ویرایش کنند یا رویداد را در تقویم خود ذخیره کنند.

در اینجا یک قطعه کد است که رویدادی را در 19 ژانویه 2012 برنامه ریزی می کند که از ساعت 7:30 صبح تا 8:30 صبح اجرا می شود به نکات زیر در مورد این قطعه کد توجه کنید:

  • Events.CONTENT_URI به عنوان Uri مشخص می کند.
  • از فیلدهای اضافی CalendarContract.EXTRA_EVENT_BEGIN_TIME و CalendarContract.EXTRA_EVENT_END_TIME برای پر کردن فرم از قبل با زمان رویداد استفاده می کند. مقادیر این زمان ها باید بر حسب UTC میلی ثانیه از دوره باشد.
  • از فیلد اضافی Intent.EXTRA_EMAIL برای ارائه فهرستی از دعوت‌شدگان جدا شده با کاما، که با آدرس ایمیل مشخص شده‌اند، استفاده می‌کند.

کاتلین

val startMillis: Long = Calendar.getInstance().run {
    set(2012, 0, 19, 7, 30)
    timeInMillis
}
val endMillis: Long = Calendar.getInstance().run {
    set(2012, 0, 19, 8, 30)
    timeInMillis
}
val intent = Intent(Intent.ACTION_INSERT)
        .setData(CalendarContract.Events.CONTENT_URI)
        .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis)
        .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis)
        .putExtra(CalendarContract.Events.TITLE, "Yoga")
        .putExtra(CalendarContract.Events.DESCRIPTION, "Group class")
        .putExtra(CalendarContract.Events.EVENT_LOCATION, "The gym")
        .putExtra(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY)
        .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com")
startActivity(intent)

جاوا

Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 0, 19, 8, 30);
Intent intent = new Intent(Intent.ACTION_INSERT)
        .setData(Events.CONTENT_URI)
        .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
        .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
        .putExtra(Events.TITLE, "Yoga")
        .putExtra(Events.DESCRIPTION, "Group class")
        .putExtra(Events.EVENT_LOCATION, "The gym")
        .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
        .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com");
startActivity(intent);

از یک قصد برای ویرایش یک رویداد استفاده کنید

همانطور که در به‌روزرسانی رویدادها توضیح داده شده است، می‌توانید مستقیماً یک رویداد را به‌روزرسانی کنید. اما استفاده از EDIT Intent به برنامه‌ای اجازه می‌دهد که ویرایش رویداد را به برنامه تقویم واگذار کند. وقتی کاربران ویرایش رویداد خود را در تقویم به پایان می‌رسانند، به برنامه اصلی بازگردانده می‌شوند.

در اینجا نمونه ای از intent است که عنوان جدیدی را برای یک رویداد مشخص تعیین می کند و به کاربران امکان می دهد رویداد را در تقویم ویرایش کنند.

کاتلین

val eventID: Long = 208
val uri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID)
val intent = Intent(Intent.ACTION_EDIT)
        .setData(uri)
        .putExtra(CalendarContract.Events.TITLE, "My New Title")
startActivity(intent)

جاوا

long eventID = 208;
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
Intent intent = new Intent(Intent.ACTION_EDIT)
    .setData(uri)
    .putExtra(Events.TITLE, "My New Title");
startActivity(intent);

از intent ها برای مشاهده داده های تقویم استفاده کنید

Calendar Provider دو روش مختلف برای استفاده از VIEW Intent ارائه می دهد:

  • برای باز کردن تقویم در یک تاریخ خاص.
  • برای مشاهده یک رویداد

در اینجا یک مثال است که نحوه باز کردن تقویم را در یک تاریخ خاص نشان می دهد:

کاتلین

val startMillis: Long
...
val builder: Uri.Builder = CalendarContract.CONTENT_URI.buildUpon()
        .appendPath("time")
ContentUris.appendId(builder, startMillis)
val intent = Intent(Intent.ACTION_VIEW)
        .setData(builder.build())
startActivity(intent)

جاوا

// A date-time specified in milliseconds since the epoch.
long startMillis;
...
Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
builder.appendPath("time");
ContentUris.appendId(builder, startMillis);
Intent intent = new Intent(Intent.ACTION_VIEW)
    .setData(builder.build());
startActivity(intent);

در اینجا یک مثال است که نشان می دهد چگونه یک رویداد را برای مشاهده باز کنید:

کاتلین

val eventID: Long = 208
...
val uri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID)
val intent = Intent(Intent.ACTION_VIEW).setData(uri)
startActivity(intent)

جاوا

long eventID = 208;
...
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
Intent intent = new Intent(Intent.ACTION_VIEW)
   .setData(uri);
startActivity(intent);

همگام سازی آداپتورها

تنها تفاوت‌های جزئی در نحوه دسترسی یک برنامه کاربردی و یک آداپتور همگام‌سازی به ارائه‌دهنده تقویم وجود دارد:

  • یک آداپتور همگام‌سازی باید با تنظیم CALLER_IS_SYNCADAPTER روی true ، مشخص کند که آداپتور همگام‌سازی است.
  • یک آداپتور همگام‌سازی باید یک ACCOUNT_NAME و یک ACCOUNT_TYPE را به عنوان پارامترهای جستجو در URI ارائه کند.
  • یک آداپتور همگام‌سازی به ستون‌های بیشتری نسبت به برنامه یا ویجت دسترسی دارد. به عنوان مثال، یک برنامه کاربردی فقط می‌تواند چند ویژگی یک تقویم را تغییر دهد، مانند نام، نام نمایشی، تنظیمات قابلیت مشاهده، و اینکه آیا تقویم همگام‌سازی شده است یا خیر. در مقایسه، یک آداپتور همگام‌سازی می‌تواند نه تنها به آن ستون‌ها، بلکه به بسیاری دیگر مانند رنگ تقویم، منطقه زمانی، سطح دسترسی، مکان و غیره دسترسی داشته باشد. با این حال، یک آداپتور همگام‌سازی به ACCOUNT_NAME و ACCOUNT_TYPE مشخص شده محدود شده است.

در اینجا یک روش کمکی وجود دارد که می توانید برای بازگرداندن یک URI برای استفاده با یک آداپتور همگام سازی استفاده کنید:

کاتلین

fun asSyncAdapter(uri: Uri, account: String, accountType: String): Uri {
    return uri.buildUpon()
            .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
            .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, account)
            .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, accountType).build()
}

جاوا

static Uri asSyncAdapter(Uri uri, String account, String accountType) {
    return uri.buildUpon()
        .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")
        .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
        .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
 }