مقدّم خدمة التقويم هو مستودع لأحداث التقويم الخاصة بالمستخدم. تشير رسالة الأشكال البيانية تتيح لك واجهة برمجة التطبيقات Calendar Provider API إجراء طلبات البحث وإدراجها وتعديلها وحذفها. والعمليات على التقاويم والأحداث والحضور والتذكيرات وما إلى ذلك.
يمكن استخدام واجهة برمجة التطبيقات لمزود التقويم بواسطة التطبيقات ومحوّلات المزامنة. تشير رسالة الأشكال البيانية حسب نوع البرنامج الذي يجري الاتصالات. هذا المستند بشكل أساسي على استخدام واجهة برمجة تطبيقات مزود التقويم كتطبيق. بالنسبة مناقشة أوجه اختلاف محوّلات المزامنة، يمكنك مراجعة محوّلات المزامنة:
في العادة، لقراءة بيانات التقويم أو كتابتها، يجب أن يحتوي بيان التطبيق على الأذونات المناسبة الموضّحة في أذونات المستخدمين. لتسهيل تنفيذ العمليات الشائعة، يقدّم Calendar Provider مجموعة من الأهداف، كما هو موضّح في Calendar Intents. تنقل هذه الأهداف المستخدمين إلى تطبيق التقويم لإدراج الأحداث وتعديلها. يتفاعل المستخدم مع تطبيق "تقويم Google" ثم يعود إلى التطبيق الأصلي. وبالتالي لا يحتاج تطبيقك إلى طلب أذونات، ولا تحتاج أيضًا إلى توفير واجهة مستخدم لعرض الأحداث أو إنشائها.
الأساسيات
يخزّن موفرو المحتوى البيانات ويتيحون الوصول إليها التطبيقات. عادةً ما يعرض مقدّمو المحتوى الذين يوفّرهم نظام Android (بما في ذلك مقدّم خدمة "تقويم Google") البيانات كمجموعة من الجداول استنادًا إلى نموذج قاعدة بيانات علائقية، حيث يكون كل صف سجلًا وكل عمود بيانات من نوع معيّن ومعنى معيّن. من خلال واجهة برمجة تطبيقات مزود التقويم، بمحولات المزامنة الحصول على حق الوصول للقراءة/الكتابة إلى جداول قاعدة البيانات التي تحتوي على بيانات تقويم المستخدم.
يعرض كل مقدّم محتوى معرّف موارد منتظمًا متاحًا للجميع (مُغلفًا كUri
عنصر) يحدّد مجموعة بياناته بشكل فريد. هو موفّر محتوى يتحكّم
تعرض مجموعات بيانات متعددة (جداول متعددة) معرف موارد منتظم (URI) منفصل لكل مجموعة. الكل
تبدأ معرفات الموارد المنتظمة (URI) للموفرين بالسلسلة "content:// ". ويؤدي ذلك إلى تحديد البيانات على أنّها تخضع للتحكّم من قِبل مقدّم محتوى. التقويم
يحدّد موفّر الخدمة الثوابت لمعرّفات الموارد المنتظمة (URI) لكل فئة من فئاته (الجداول). تكون عناوين URI هذه بالتنسيق <class>.CONTENT_URI
. على سبيل المثال، Events.CONTENT_URI
.
يعرض الشكل 1 تمثيلاً رسوميًا لنموذج بيانات مزوّد خدمة التقويم. ويعرض الجداول الرئيسية والحقول التي تربطها ببعضها.
يمكن أن يكون لدى المستخدم تقاويم متعددة، ويمكن ربط التقاويم المختلفة بأنواع مختلفة من الحسابات ("تقويم Google" وExchange وما إلى ذلك).
تحدِّد CalendarContract
نموذج البيانات الخاص بالتقويم والمعلومات ذات الصلة بالحدث. يتم تخزين هذه البيانات في عدد من الجداول المدرجة أدناه.
الجدول (الفئة) | الوصف |
---|---|
يحتوي هذا الجدول على المعلومات المتعلّقة بالتقويم. يحتوي كل صف في هذا الجدول على تفاصيل تقويم واحد، مثل الاسم واللون ومعلومات المزامنة وما إلى ذلك. | |
CalendarContract.Events |
يحتوي هذا الجدول على
الخاصة بالحدث. يحتوي كل صف في هذا الجدول على معلومات عن
حدث، مثل عنوان الحدث والموقع الجغرافي ووقت البدء والانتهاء
والوقت وهكذا. قد يحدث الحدث لمرة واحدة أو يتكرّر عدة مرات. الضيوف،
والتذكيرات والخصائص الموسعة في جداول منفصلة.
يحتوي كلّ منها على EVENT_ID
يشير إلى _ID في جدول "الأحداث". |
CalendarContract.Instances |
يحتوي هذا الجدول على وقت البدء والانتهاء لكلّ مرّة من مرّات حدوث الحدث. يمثّل كل صف في هذا الجدول موضع حدوث حدث واحد. بالنسبة إلى الأحداث لمرة واحدة، يتمّ ربط المثيلات بالأحداث بنسبة 1:1. بالنسبة إلى الأحداث المتكرّرة، يتم إنشاء صفوف متعددة تلقائيًا تم إنشاؤه بشكل يتوافق مع التكرارات المتعددة لهذا الحدث. |
CalendarContract.Attendees |
يحتوي هذا الجدول على معلومات الحضور (الضيوف) في الحدث. يمثّل كل صف ضيفًا واحدًا في أحد الأحداث. وهي تحدّد نوع الضيف وردّه بشأن حضوره للفعالية. |
CalendarContract.Reminders |
يحتوي هذا الجدول على
بيانات التنبيهات أو الإشعارات. يمثّل كل صف تنبيهًا واحدًا لحدث معيّن. يمكن أن يتضمّن
الحدث تذكيرات متعددة. يتم تحديد الحد الأقصى لعدد التذكيرات لكل حدث في MAX_REMINDERS ، والذي يتم ضبطه بواسطة محوِّل المزامنة الذي يملك التقويم المحدَّد. يتم تحديد التذكيرات خلال دقائق قبل الحدث.
وتمتلك طريقة لتحديد كيفية تنبيه المستخدم. |
تم تصميم واجهة برمجة التطبيقات Calendar Provider API لتكون مرنة وفعّالة. في الوقت نفسه، من المهم توفير تجربة جيدة للمستخدم النهائي و حماية سلامة التقويم وبياناته. لتحقيق هذا الهدف، إليك بعض النقاط التي يجب أخذها في الاعتبار عند استخدام واجهة برمجة التطبيقات:
- إدراج أحداث التقويم وتعديلها وعرضها لإدراج الأحداث من "موفِّر التقويم" وتعديلها وقراءتها مباشرةً، يجب الحصول على الأذونات المناسبة. ومع ذلك، إذا كنت لا تنشئ تطبيق تقويم كاملاً أو محوّل مزامنة، لن يكون من الضروري طلب هذه الأذونات. يمكنك بدلاً من ذلك استخدام النوايا المتوافقة مع تطبيق "تقويم Google" على Android لنقل عمليات القراءة والكتابة إلى هذا التطبيق. عند استخدام عناصر intent، يرسل تطبيقك المستخدمين إلى تطبيق "تقويم Google" لتنفيذ العملية المطلوبة في نموذج مملوء مسبقًا. وبعد الانتهاء، تتم إعادتها إلى تطبيقك. من خلال تصميم تطبيقك لتنفيذ عمليات شائعة من خلال التقويم، تزويد المستخدمين بواجهة مستخدم متسقة وفعّالة. هذه هي نهجًا موصى به. لمزيد من المعلومات، يُرجى الاطّلاع على تقويم Google Intents.
- محولات المزامنة: يعمل محوِّل المزامنة على مزامنة بيانات التقويم
على جهاز المستخدم مع خادم أو مصدر بيانات آخر. في جدولَي
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
حساب
تمت المزامنة.
الاستعلام عن تقويم
في ما يلي مثال يوضّح كيفية الحصول على التقاويم التي يملكها مستخدم معيّن. من أجل التبسيط، يتم عرض عملية طلب البحث في مثالنا هذا في سلسلت محادثات واجهة المستخدِم ("السلسلة الرئيسية"). من الناحية العملية، يجب إجراء ذلك في سلسلة تعليمات
غير متزامنة بدلاً من السلسلة الرئيسية. لمزيد من المناقشة، يُرجى الاطّلاع على
أدوات التحميل. إذا لم تكن مجرد
قراءة البيانات وتعديلها، راجِع AsyncQueryHandler
.
Kotlin
// 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
Java
// 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
يمكنك استخدامه للتنقّل في مجموعة النتائج التي يعرضها استعلام قاعدة البيانات
. لمزيد من المناقشة حول استخدام طلبات البحث في موفّري المحتوى،
راجِع موفّرو المحتوى.
Kotlin
// 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)
Java
// 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);
يستخدم هذا القسم التالي المؤشر للتنقّل في مجموعة النتائج. فهي تستخدم الثوابت التي تم وضعها في بداية المثال لإرجاع القيم لكل حقل.
Kotlin
// 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... }
Java
// 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
للتقويم إما كرقم تعريف مرفق بملف تعريف الموارد (withAppendedId()
) أو كأول عنصر اختيار. الاختيار
يجب أن يبدأ بـ "_id=?"
، وأول
يجب أن يكون selectionArg
هو _ID
في التقويم.
ويمكنك أيضًا إجراء تعديلات من خلال ترميز رقم التعريف في عنوان URI. يغير هذا المثال
الاسم المعروض للتقويم باستخدام
(withAppendedId()
)
:
Kotlin
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")
Java
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 |
وقت بدء الحدث بالمللي ثانية بالتوقيت العالمي المنسق منذ الحقبة |
DTEND |
وقت انتهاء الحدث بالمللي ثانية بالتوقيت العالمي المنسق منذ الحقبة |
EVENT_TIMEZONE |
المنطقة الزمنية للحدث |
EVENT_END_TIMEZONE |
المنطقة الزمنية لوقت انتهاء الحدث. |
DURATION |
مدة الحدث بتنسيق RFC5545
على سبيل المثال، تشير قيمة "PT1H" إلى أنّ الحدث
ينبغي أن تستمر لمدة ساعة واحدة، وتشير القيمة "P2W" إلى
أسبوعَين. |
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
الغرض، كما هو موضَّح في استخدام نية لإدراج حدث. ومع ذلك، إذا
كنت بحاجة إلى ذلك، يمكنك إدراج الأحداث مباشرةً. يصف هذا القسم كيفية إجراء
هذا.
في ما يلي قواعد إدراج حدث جديد:
- يجب تضمين
CALENDAR_ID
وDTSTART
. - يجب تضمين
EVENT_TIMEZONE
. للحصول على قائمة من معرّفات المنطقة الزمنية المثبّتة للنظام، استخدِم السمةgetAvailableIDs()
. يُرجى العلم أنّ هذه القاعدة لا تنطبق في حال إدراج حدث من خلال نيةINSERT
الموضّحة في مقالة استخدام نية لإدراج حدث. وفي هذا السيناريو، يتم توفير منطقة زمنية تلقائية. - بالنسبة إلى الأحداث غير المتكرّرة، يجب تضمين
DTEND
. - بالنسبة إلى الأحداث المتكرّرة، يجب تضمين
DURATION
بالإضافة إلىRRULE
أوRDATE
. لاحظ أن هذه القاعدة لا تنطبق إذا إذا كنت تدرج حدثًا من خلال نيةINSERT
الموضَّحة في المقالة استخدام نية لإدراج حدث، وفي ما يلي: يمكنك استخدامRRULE
معDTSTART
وDTEND
، وتطبيق "تقويم Google" وتحوله إلى مدة تلقائيًا.
في ما يلي مثال على إدراج حدث. يتم تنفيذه في واجهة المستخدم
سلسلة محادثات لتبسيط الأمر. عمليًا، يجب إجراء الإدخالات والتحديثات في
سلسلة محادثات غير متزامنة لنقل الإجراء إلى سلسلة محادثات في الخلفية. لمزيد من المعلومات،
المعلومات، يمكنك الاطّلاع على AsyncQueryHandler
.
Kotlin
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 // //
Java
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
،
كما هو موضَّح في مقالة استخدام هدف لتعديل حدث.
ومع ذلك، يمكنك تعديل الأحداث مباشرةً، إذا كنت بحاجة إلى ذلك. لإجراء تحديث
حدث، فيمكنك تقديم _ID
الحدث إما كمعرّف ملحق في معرّف الموارد المنتظم (URI) (withAppendedId()
)
أو كعنصر التحديد الأول.
يجب أن يبدأ التحديد بـ "_id=?"
، وأول
يجب أن يكون selectionArg
هو _ID
للحدث. يمكنك
أيضًا إجراء التحديثات باستخدام تحديد بدون معرّف. فيما يلي مثال على تحديث
فعالية. يغير عنوان الحدث باستخدام
withAppendedId()
:
Kotlin
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")
Java
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
كرقم تعريف مرفق في عنوان URL أو باستخدام
الاختيار العادي. في حال استخدام معرّف مرفق، لا يمكنك أيضًا إجراء اختيار.
هناك إصداران من ميزة "الحذف": كتطبيق وكأداة ربط مزامنة. يؤدي
حذف تطبيق إلى ضبط العمود deleted على 1. هذه العلامة التي تُعلم
محوِّل المزامنة بأنّه تم حذف الصف وأنّه يجب
نشر هذا الحذف على الخادم. يؤدي حذف محوِّل المزامنة إلى إزالة الحدث من قاعدة بياناته
بالإضافة إلى جميع البيانات المرتبطة به. إليك مثال على أحد التطبيقات
حذف حدث من خلال _ID
:
Kotlin
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")
Java
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
:
Kotlin
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)
Java
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 قبل الحدث بدقائق.
Kotlin
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)
Java
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 |
وقت بدء الإصدار، بالمللي ثانية بالتوقيت العالمي المنسّق |
END |
وقت انتهاء النسخة، بالمللي ثانية بالتوقيت العالمي المنسّق |
END_DAY |
يوم انتهاء Julian للمثيل، بالنسبة إلى وقت التقويم المنطقة. |
END_MINUTE |
دقيقة انتهاء الحدث، ويتم احتسابها من منتصف الليل في المنطقة الزمنية التي يستخدمها "تقويم Google". |
EVENT_ID |
_ID للحدث لهذا المثيل. |
START_DAY |
يوم البدء الجولياني للمثيل، بالنسبة إلى المنطقة الزمنية للتقويم. |
START_MINUTE |
دقيقة بدء الحدث، محسوبة من منتصف الليل، بالنسبة إلى المنطقة الزمنية التي يستخدمها "تقويم Google" |
الاستعلام عن جدول المثيلات
للاستعلام عن جدول المثيلات، تحتاج إلى تحديد وقت نطاق للاستعلام
في عنوان URI. في هذا المثال، يحصل CalendarContract.Instances
على إذن الوصول إلى الحقل TITLE
من خلال
تنفيذ واجهة CalendarContract.EventsColumns
.
بعبارة أخرى، يتم عرض TITLE
من خلال
عرض قاعدة بيانات، وليس من خلال طلب بحث في جدول CalendarContract.Instances
الأوّلي.
Kotlin
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)}") }
Java
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())); } }
نوايا "تقويم Google"
لا يحتاج تطبيقك إلى أذونات لقراءة بيانات التقويم وكتابتها. وبدلاً من ذلك، يمكنه استخدام عناصر intent التي يتيحها تطبيق "تقويم Google" على Android لتسليم عمليات القراءة والكتابة إلى هذا التطبيق. يعرض الجدول التالي الأهداف المتوافقة مع موفّر "تقويم Google":
الإجراء | URI | الوصف | المحتوى الإضافي |
---|---|---|---|
VIEW |
CalendarContract.CONTENT_URI .
للاطّلاع على مثال لاستخدام هذا الإجراء، راجِع مقالة استخدام الإجراءات لعرض بيانات التقويم.
|
فتح التقويم وفقًا للوقت الذي يحدده <ms_since_epoch> . |
بلا عُري |
Events.CONTENT_URI .
للحصول على مثال على استخدام هذا الغرض، راجِع استخدام الأهداف لعرض بيانات التقويم.
|
عرض الحدث المحدّد من قِبل "<event_id> " |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
|
EDIT |
Events.CONTENT_URI
للحصول على مثال على استخدام هذا الغرض، اطّلِع على استخدام نية لتعديل حدث.
|
عدِّل الحدث المحدَّد بالرمز <event_id> . |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
EDIT INSERT |
Events.CONTENT_URI .
للاطّلاع على مثال لاستخدام هذا الإجراء، اطّلِع على استخدام إجراء لإدراج حدث.
|
أنشِئ حدثًا. | أي من الميزات الإضافية المدرجة في الجدول أدناه. |
يسرد الجدول التالي عناصر الأهداف الإضافية التي يوفّرها موفّر "تقويم Google":
نية قوية بالشراء | الوصف |
---|---|
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
لتطبيقك تسليم مهمة إدراج الحدث إلى "تقويم Google" نفسه.
باستخدام هذا النهج، لا يحتاج تطبيقك إلى تضمين الإذن WRITE_CALENDAR
في ملف البيان.
عندما يشغّل المستخدمون تطبيقًا يستخدم هذا النهج، يرسلهم التطبيق
إلى "تقويم Google" لإنهاء إضافة الحدث. يستخدم Intent في "INSERT
" حقولاً إضافية من أجل
تعبئة نموذج مسبقًا بتفاصيل الحدث في التقويم. يمكن للمستخدمين
بعد ذلك إلغاء الحدث أو تعديل النموذج حسب الحاجة أو حفظ الحدث في
تقويماتهم.
في ما يلي مقتطف رمز يحدد موعدًا لحدث في 19 كانون الثاني (يناير) 2012، يتم تشغيله من 7:30 صباحًا حتى 8:30 صباحًا. لاحظ ما يلي عن مقتطف الرمز هذا:
- ويحدّد هذا العنصر
Events.CONTENT_URI
. باسم معرف الموارد المنتظم (URI). - ويستخدم الحقلَين
CalendarContract.EXTRA_EVENT_BEGIN_TIME
وCalendarContract.EXTRA_EVENT_END_TIME
الإضافيَين لتعبئة النموذج تلقائيًا بوقت الحدث. يجب أن تكون قيم هذه الأوقات بالمللي ثانية بالتوقيت العالمي المنسق (UTC) من هذه الحقبة. - ويستخدم الحقل
Intent.EXTRA_EMAIL
الإضافي لتوفير قائمة بالمدعوين مفصولة بفواصل، ويتم تحديدها حسب عنوان البريد الإلكتروني.
Kotlin
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)
Java
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
، يُسمح لتطبيق ليس لديه إذن بنقل تعديل الحدث إلى تطبيق "تقويم Google".
عندما ينتهي المستخدمون من تعديل الحدث في "تقويم Google"، تتم إعادتهم إلى
التطبيق الأصلي.
في ما يلي مثال على نية تحدّد عنوانًا جديدًا لحدث محدّد وتسمح للمستخدمين بتعديل الحدث في "تقويم Google".
Kotlin
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)
Java
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:
- لفتح التقويم إلى تاريخ معين.
- لعرض حدث:
في ما يلي مثال يوضّح كيفية فتح "تقويم Google" لتاريخ معيّن:
Kotlin
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)
Java
// 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);
في ما يلي مثال يوضّح كيفية فتح حدث للعرض:
Kotlin
val eventID: Long = 208 ... val uri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID) val intent = Intent(Intent.ACTION_VIEW).setData(uri) startActivity(intent)
Java
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) لاستخدامه مع محوِّل مزامنة:
Kotlin
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() }
Java
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(); }