«ارائهدهنده تقویم» مخزنی برای رویدادهای تقویم کاربر است. Calendar Provider API به شما امکان میدهد عملیات پُرسمان، درج، بهروزرسانی، و حذف را روی مواردی مانند تقویمها، رویدادها، شرکتکنندگان، و یادآوریها انجام دهید.
برنامهها و وفقدهندههای همگامسازی میتوانند از Calendar Provider API استفاده کنند. قوانین بسته به نوع برنامهای که تماسها را برقرار میکند متفاوت است. این سند عمدتاً بر استفاده از Calendar Provider API بهعنوان یک برنامه تمرکز دارد. برای بحث درباره تفاوت وفقدهندههای همگامسازی، به وفقدهندههای همگامسازی مراجعه کنید.
معمولاً برای خواندن یا نوشتن دادههای تقویم، مانیفست برنامه باید شامل اجازههای مناسب باشد که در اجازههای کاربر شرح داده شده است. برای آسانتر کردن انجام عملیات رایج، «ارائهدهنده تقویم» مجموعهای از هدفها را ارائه میدهد، همانطور که در هدفهای تقویم شرح داده شده است. این هدفها کاربران را به برنامه «تقویم» میبرند تا رویدادها را درج، مشاهده، و ویرایش کنند. کاربر با برنامه «تقویم» تعامل میکند و سپس به برنامه اصلی برمیگردد. بنابراین، برنامهتان نیازی به درخواست اجازهها ندارد، و نیازی هم به ارائه میانای کاربر برای مشاهده یا ایجاد رویدادها ندارد.
اصول اولیه
ارائهدهندگان محتوا دادهها را ذخیره میکنند و آنها را برای برنامهها قابلدسترس میکنند. ارائهدهندگان محتوا که توسط پلاتفرم Android ارائه میشوند (ازجمله «ارائهدهنده تقویم») معمولاً دادهها را بهعنوان مجموعهای از جدولها براساس مدل پایگاه داده رابطهای نشان میدهند که در آن هر ردیف یک رکورد است و هر ستون دادهای از نوع و معنای خاص است. ازطریق Calendar Provider API، برنامهها و وفقدهندههای همگامسازی میتوانند به جدولهای پایگاه داده که دادههای تقویم کاربر را نگه میدارند دسترسی خواندن/نوشتن داشته باشند.
هر ارائهدهنده محتوا یک URI عمومی (که بهعنوان یک شیء
Uri
بستهبندی شده است) را درمعرض دید قرار میدهد که بهطور منحصربهفرد مجموعه دادههای آن را شناسایی میکند. ارائهدهنده محتوایی که چندین مجموعه داده (چندین جدول) را کنترل میکند، برای هرکدام یک URI جداگانه ارائه میدهد. همه
شناسههای منبع یکسان برای ارائهدهندگان با رشته «content://» شروع میشوند. این
مشخص میکند که دادهها توسط ارائهدهنده محتوا کنترل میشود. «ارائهدهنده تقویم»
ثابتهایی را برای URIهای هریک از کلاسهایش (جدولها) تعریف میکند. این
شناسههای منبع یکسان قالب <class>.CONTENT_URI دارند. برای مثال، Events.CONTENT_URI.
شکل ۱ نمایش گرافیکی مدل داده «ارائهدهنده تقویم» را نشان میدهد. این نمودار جدولهای اصلی و فیلدهایی را که آنها را به یکدیگر پیوند میدهد نشان میدهد.
کاربر میتواند چند تقویم داشته باشد و تقویمهای مختلف میتوانند با انواع مختلف حساب (تقویم Google، Exchange، و غیره) مرتبط باشند.
CalendarContract مدل داده اطلاعات مربوط به تقویم و رویداد را تعریف میکند. این دادهها در تعدادی جدول ذخیره میشوند که در زیر فهرست شدهاند.
| جدول (کلاس) | شرح |
|---|---|
| این جدول حاوی اطلاعات مختص تقویم است. هر ردیف در این جدول حاوی جزئیات مربوط به یک تقویم است، مانند نام، رنگ، و اطلاعات همگامسازی. | |
CalendarContract.Events |
این جدول حاوی اطلاعات مختص رویداد است. هر ردیف در این جدول اطلاعات مربوط به یک رویداد را دارد—برای مثال، عنوان رویداد، مکان، زمان شروع، زمان پایان. رویداد میتواند یکبار اتفاق بیفتد یا چندینبار تکرار شود. شرکتکنندگان،
یادآوریها، و ویژگیهای گسترشیافته در جدولهای جداگانه ذخیره میشوند.
هرکدام یک EVENT_ID دارند
که به _ID در جدول «رویدادها» ارجاع میدهد. |
CalendarContract.Instances |
این جدول زمان شروع و پایان هر رخداد رویداد را نگه میدارد. هر ردیف در این جدول نشاندهنده یک رخداد رویداد است. برای رویدادهای یکباره، نگاشت ۱:۱ از نمونهها به رویدادها وجود دارد. برای رویدادهای تکرارشونده، چندین ردیف بهطور خودکار تولید میشود که با چندین تکرار آن رویداد مطابقت دارد. |
CalendarContract.Attendees |
این جدول حاوی اطلاعات شرکتکننده (مهمان) رویداد است. هر ردیف نشاندهنده یک مهمان رویداد است. این عنصر نوع مهمان و پاسخ حضور مهمان را برای رویداد مشخص میکند. |
CalendarContract.Reminders |
این جدول حاوی دادههای هشدار/اعلان است. هر ردیف نشاندهنده یک هشدار برای رویداد است. یک رویداد میتواند چندین یادآور داشته باشد. حداکثر تعداد یادآوریها برای هر رویداد در
MAX_REMINDERS
مشخص شده است،
که توسط وفقدهنده همگامسازی که
مالک تقویم دادهشده است تنظیم میشود. یادآوریها براساس دقیقه قبلاز رویداد مشخص میشوند
و روشی دارند که نحوه هشدار به کاربر را تعیین میکند. |
Calendar Provider API بهگونهای طراحی شده است که انعطافپذیر و قدرتمند باشد. درعینحال، ارائه تجربه کاربری خوب برای کاربر نهایی و محافظت از یکپارچگی تقویم و دادههای آن مهم است. به این منظور، در اینجا چند نکته برای استفاده از API آورده شده است:
- درج، بهروزرسانی، و مشاهده رویدادهای تقویم. برای درج، اصلاح، و خواندن مستقیم رویدادها از «ارائهدهنده تقویم»، به اجازههای مناسب نیاز دارید. بااینحال، اگر برنامه تقویم یا وفقدهنده همگامسازی کاملی نمیسازید، درخواست این اجازهها ضروری نیست. بهجای آن میتوانید از هدفهای پشتیبانیشده توسط برنامه «تقویم» Android برای واگذاری عملیات خواندن و نوشتن به آن برنامه استفاده کنید. وقتی از هدفها استفاده میکنید، برنامهتان کاربران را به برنامه «تقویم» میفرستد تا عملیات انتخابشده را در فرمی ازپیش تکمیلشده انجام دهند. پساز اتمام کار، به برنامه شما برگردانده میشوند. با طراحی برنامهتان برای انجام عملیات رایج ازطریق «تقویم»، میانای کاربر منسجم و قدرتمندی را دراختیار کاربران قرار میدهید. این رویکرد توصیه میشود. برای اطلاعات بیشتر، قصدهای تقویم را ببینید.
- وفقدهندههای همگامسازی. وفقدهنده همگامسازی دادههای تقویم را در دستگاه کاربر با سرور یا منبع داده دیگری همگامسازی میکند. در جدولهای
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 نشان میدهد که رویدادهای مرتبط با این تقویم نباید نشان داده شود. مقدار ۱ نشان میدهد که رویدادهای مرتبط با این تقویم باید
نشان داده شود. این مقدار بر تولید ردیفها در جدول CalendarContract.Instances تأثیر میگذارد. |
SYNC_EVENTS |
بولی نشاندهنده اینکه آیا تقویم باید همگامسازی شود و رویدادهای آن در دستگاه ذخیره شود یا نه. مقدار ۰ یعنی این تقویم همگامسازی نشود یا رویدادهای آن در دستگاه ذخیره نشود. مقدار ۱ یعنی رویدادهای این تقویم همگامسازی شود و رویدادهای آن در دستگاه ذخیره شود. |
نوع حساب را برای همه عملیاتها اضافه کنید
اگر در Calendars.ACCOUNT_NAME پُرسمان میکنید، باید
Calendars.ACCOUNT_TYPE
را نیز در انتخاب اضافه کنید. دلیلش این است که یک حساب مشخص فقط با داشتن هر دو ACCOUNT_NAME و ACCOUNT_TYPE منحصربهفرد درنظر گرفته میشود. ACCOUNT_TYPE رشتهای است که با اصالتسنج حساب که هنگام ثبت حساب با AccountManager استفاده شده است مطابقت دارد. نوع خاصی از حساب نیز وجود دارد
که ACCOUNT_TYPE_LOCAL نامیده میشود و برای
تقویمهایی است که با حساب دستگاه مرتبط نیستند.
حسابهای ACCOUNT_TYPE_LOCAL همگامسازی نمیشوند.
پرسوجو کردن تقویم
در اینجا مثالی آورده شده است که نشان میدهد چگونه تقویمهایی را که متعلق به یک کاربر خاص هستند دریافت کنید. برای سادگی، در این مثال عملیات پُرسمان در رشته میانای کاربر («رشته اصلی») نشان داده شده است. در عمل، این کار باید در یک رشته ناهمگام بهجای رشته اصلی انجام شود. برای بحث بیشتر، به
بارکنندهها مراجعه کنید. اگر فقط دادهها را نمیخوانید بلکه آنها را اصلاح میکنید، 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" نشاندهنده مدت ۲ هفته است. |
ALL_DAY |
مقدار ۱ نشان میدهد که این رویداد کل روز را اشغال میکند، همانطور که توسط منطقه زمانی محلی تعریف شده است. مقدار ۰ نشان میدهد که رویداد معمولی است و ممکن است در هر زمانی از روز شروع و تمام شود. |
RRULE |
قانون تکرار برای قالب رویداد. برای مثال، "FREQ=WEEKLY;COUNT=10;WKST=SU". برای
نمونههای بیشتر، مشخصات RFC5545 را ببینید. |
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()استفاده کنید. توجه داشته باشید که اگر رویدادی را ازطریقINSERTIntent وارد میکنید، این قانون اعمال نمیشود. این موضوع در استفاده از Intent برای درج رویداد توضیح داده شده است—در این سناریو، منطقه زمانی پیشفرض ارائه میشود. - برای رویدادهای غیرتکرارشونده، باید
DTENDرا اضافه کنید. - برای رویدادهای تکرارشونده، باید علاوهبر
RRULEیاRDATE،DURATIONرا هم اضافه کنید. توجه داشته باشید که اگر رویدادی را ازطریقINSERTIntent درج میکنید، این قانون اعمال نمیشود. این موضوع در استفاده از Intent برای درج رویداد شرح داده شده است—در این سناریو، میتوانید ازRRULEدر کنارDTSTARTوDTENDاستفاده کنید و برنامه «تقویم» آن را بهطور خودکار به مدت تبدیل میکند.
در اینجا نمونهای از درج رویداد آورده شده است. این کار برای سادگی در رشته میانای کاربر انجام میشود. در عمل، درج و بهروزرسانی باید در رشتهای ناهمگام انجام شود تا کنش به رشته پسزمینه منتقل شود. برای اطلاعات بیشتر، به 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
رویداد را بهعنوان شناسه پیوستشده به شناسه منبع یکسان (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 یا بااستفاده از
انتخاب استاندارد حذف کنید. اگر از شناسه پیوستشده استفاده میکنید، نمیتوانید انتخاب هم انجام دهید.
دو نسخه از حذف وجود دارد: بهعنوان برنامه و بهعنوان وفقدهنده همگامسازی. حذف برنامه، ستون حذفشده را روی ۱ تنظیم میکند. این پرچم به وفقدهنده همگامسازی میگوید که ردیف حذف شده است و این حذف باید به سرور منتقل شود. حذف وفقدهنده همگامسازی رویداد را بههمراه همه دادههای منسوب به آن از پایگاه داده برمیدارد. در اینجا نمونهای از حذف رویداد توسط برنامه ازطریق _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 |
روش هشدار، همانطور که در سرور تنظیم شده است. یکی از: |
افزودن یادآوریها
این مثال یادآوری را به رویداد اضافه میکند. یادآور ۱۵ دقیقه قبلاز رویداد فعال میشود.
کاتلین
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 |
دقیقه شروع نمونه که از نیمهشب نسبت به منطقه زمانی «تقویم» اندازهگیری میشود. |
پرسوجو کردن جدول نمونهها
برای پُرسمان جدول «نمونهها»، باید محدوده زمانی پُرسمان را در 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())); } }
هدفهای تقویم
برنامه شما برای خواندن و نوشتن دادههای تقویم به اجازه نیاز ندارد. درعوض، میتواند از هدفهای پشتیبانیشده توسط برنامه «تقویم» Android برای واگذاری عملیات خواندن و نوشتن به آن برنامه استفاده کند. جدول زیر هدفهای پشتیبانیشده توسط «ارائهدهنده تقویم» را فهرست میکند:
| کنش | URI | شرح | جایزهها |
|---|---|---|---|
VIEW |
CalendarContract.CONTENT_URI مراجعه کنید.
برای نمونهای از استفاده از این هدف، به استفاده از اهداف برای مشاهده دادههای تقویم مراجعه کنید.
|
تقویم را در زمان مشخصشده توسط <ms_since_epoch> باز کنید. |
هیچکدام. |
Events.CONTENT_URI مراجعه کنید.
برای نمونهای از استفاده از این هدف، به استفاده از اهداف برای مشاهده دادههای تقویم مراجعه کنید.
|
مشاهده رویداد مشخصشده توسط <event_id>. |
CalendarContract.EXTRA_EVENT_BEGIN_TIMECalendarContract.EXTRA_EVENT_END_TIME |
|
EDIT |
Events.CONTENT_URI مراجعه کنید.
برای مشاهده نمونهای از استفاده از این هدف، به استفاده از هدف برای ویرایش رویداد مراجعه کنید.
|
رویداد مشخصشده با <event_id> را ویرایش کنید. |
CalendarContract.EXTRA_EVENT_BEGIN_TIMECalendarContract.EXTRA_EVENT_END_TIME |
EDIT INSERT |
Events.CONTENT_URI مراجعه کنید.
برای مشاهده نمونهای از استفاده از این هدف، به استفاده از هدف برای درج رویداد مراجعه کنید.
|
رویدادی ایجاد کنید. | هریک از موارد اضافی فهرستشده در جدول زیر. |
جدول زیر موارد اضافی هدف را که «ارائهدهنده تقویم» پشتیبانی میکند فهرست میکند:
| Intent Extra | شرح |
|---|---|
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 |
اگر این رویداد بهعنوان زمان مشغول بهحساب میآید یا زمان آزادی است که میتوان برای آن زمانبندی کرد. |
بخشهای زیر نحوه استفاده از این قصدها را شرح میدهد.
استفاده از قصد برای درج رویداد
استفاده از INSERT Intent
به برنامه شما اجازه میدهد تا وظیفه درج رویداد را به خود «تقویم» واگذار کند.
با این رویکرد، برنامه شما حتی نیازی به داشتن اجازه WRITE_CALENDAR در فایل مانیفست خود ندارد.
وقتی کاربران برنامهای را اجرا میکنند که از این رویکرد استفاده میکند، برنامه آنها را به «تقویم» میفرستد تا افزودن رویداد را تکمیل کنند. INSERT Intent از فیلدهای اضافی برای
ازپیش تکمیل کردن فرم با جزئیات رویداد در «تقویم» استفاده میکند. سپس کاربران میتوانند رویداد را لغو کنند، فرم را درصورت نیاز ویرایش کنند، یا رویداد را در تقویمشان ذخیره کنند.
در اینجا تکهکدی وجود دارد که رویدادی را در ۱۹ ژانویه ۲۰۱۲ زمانبندی میکند که از ساعت ۷:۳۰ صبح تا ۸:۳۰ صبح اجرا میشود. به موارد زیر درباره این تکهکد توجه کنید:
-
Events.CONTENT_URIرا بهعنوان «شناسه منبع یکسان» مشخص میکند. - این الگو از فیلدهای اضافی
CalendarContract.EXTRA_EVENT_BEGIN_TIMEوCalendarContract.EXTRA_EVENT_END_TIMEبرای ازپیش تکمیل کردن فرم با زمان رویداد استفاده میکند. مقادیر این زمانها باید برحسب میلیثانیه ساعت هماهنگ جهانی از تاریخ باشد. - میانا برای ارائه فهرست جداشده با کاما از دعوتشدگان که با نشانی ایمیل مشخص شدهاند، از فیلد اضافی
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 به برنامهای که
اجازه ندارد امکان میدهد ویرایش رویداد را به برنامه «تقویم» واگذار کند.
وقتی کاربران ویرایش رویدادشان را در «تقویم» تمام میکنند، به برنامه اصلی برگردانده میشوند.
در اینجا نمونهای از قصدی را میبینید که عنوان جدیدی برای رویداد مشخصی تنظیم میکند و به کاربران اجازه میدهد رویداد را در «تقویم» ویرایش کنند.
کاتلین
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);
استفاده از هدفها برای مشاهده دادههای تقویم
«ارائهدهنده تقویم» دو روش مختلف برای استفاده از 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(); }