'ספק אנשי הקשר' הוא רכיב Android חזק וגמיש שמנהל את מאגר הנתונים המרכזי של המכשיר על אנשים. ספק אנשי הקשר הוא מקור הנתונים שמופיעים באפליקציית אנשי הקשר של המכשיר. אתם יכולים גם לגשת לנתונים שלו באפליקציה שלכם ולהעביר נתונים בין המכשיר לשירותים אונליין. הספק מבקש לקבל מגוון רחב של מקורות נתונים, ומנסה לנהל כמה שיותר נתונים עבור כל אדם, כתוצאה מכך שהארגון שלו מורכב. לכן, ה-API של הספק כולל קבוצה נרחבת של ממשקים וסיווגים של חוזים שמאפשרים גם אחזור וגם שינוי של נתונים.
במדריך הזה מתוארים הנושאים הבאים:
- המבנה הבסיסי של הספק.
- איך מאחזרים נתונים מהספק.
- איך משנים את הנתונים בספק
- איך לכתוב מתאם סנכרון לסנכרון נתונים מהשרת שלך ספק אנשי הקשר.
במדריך הזה אנחנו יוצאים מנקודת הנחה שאתם מכירים את העקרונות הבסיסיים של ספקי תוכן ל-Android. מידע נוסף על ספקי תוכן של Android, מדריך בסיסי לספקי תוכן.
הארגון של ספק אנשי הקשר
'ספק אנשי הקשר' הוא רכיב של ספק תוכן ל-Android. הוא כולל שלושה סוגים של נתונים על אדם, שכל אחד מהם תואם לטבלה שמוצעת על ידי הספק, איור 1:

איור 1. מבנה הטבלה של ספק אנשי הקשר.
שלוש הטבלאות נקראות בדרך כלל בשמות של סיווגי החוזים שלהן. הכיתות מגדירות קבועים למזהי URI של תוכן, לשמות עמודות ולערכים של עמודות שבהם משתמשות הטבלאות:
-
טבלה אחת (
ContactsContract.Contacts
) - שורות שמייצגות אנשים שונים, על סמך צבירת שורות קשר גולמיות.
-
טבלה אחת (
ContactsContract.RawContacts
) - שורות שמכילות סיכום של נתונים של משתמש, ספציפיות לחשבון ולסוג.
-
טבלה אחת (
ContactsContract.Data
) - שורות שמכילות את הפרטים של איש הקשר הגולמי, כמו כתובות אימייל או מספרי טלפון.
הטבלאות האחרות שמיוצגות על ידי כיתות חוזה ב-ContactsContract
הן טבלאות עזר שספק אנשי הקשר משתמש בהן כדי לנהל את הפעולות שלו או לתמוך
בפונקציות ספציפיות באנשי הקשר או באפליקציות הטלפוניה של המכשיר.
אנשי קשר גולמיים
איש קשר בסיסי מייצג את הנתונים של אדם שמגיעים מסוג חשבון אחד ומשם חשבון אחד. בגלל שספק אנשי הקשר מאפשר יותר משירות מקוון אחד כמקור נתונים של אדם, 'ספק אנשי הקשר' מאפשר ליצור כמה אנשי קשר גולמיים עבור אותו אדם. כמה אנשי קשר גולמיים מאפשרים למשתמש גם לשלב נתונים של אדם מיותר מחשבון אחד מאותו סוג חשבון.
רוב הנתונים של איש קשר גולמי לא מאוחסנים
טבלה של ContactsContract.RawContacts
. במקום זאת, הוא מאוחסן בשורה אחת או יותר בטבלה ContactsContract.Data
. בכל שורת נתונים יש עמודה
Data.RAW_CONTACT_ID
ש
מכיל את הערך RawContacts._ID
שורת הורה ContactsContract.RawContacts
.
עמודות גולמיות חשובות של אנשי קשר
העמודות החשובות בטבלה ContactsContract.RawContacts
מפורטות בטבלה 1. חשוב לקרוא את ההערות הבאות אחרי הטבלה:
טבלה 1. עמודות גולמיות חשובות של אנשי קשר.
שם העמודה | שימוש | הערות |
---|---|---|
ACCOUNT_NAME
|
שם החשבון של סוג החשבון שהוא המקור של איש הקשר הגולמי הזה.
לדוגמה, שם החשבון של חשבון Google הוא אחד מחשבונות Gmail של בעלי המכשיר
כתובות. מידע נוסף זמין ברשומה הבאה של ACCOUNT_TYPE .
|
הפורמט של השם הזה ספציפי לסוג החשבון. היא לא חייבת להיות כתובת אימייל. |
ACCOUNT_TYPE
|
סוג החשבון שממנו הגיע איש הקשר הגולמי הזה. לדוגמה, החשבון
הסוג של חשבון Google הוא com.google . תמיד צריך לציין את סוג החשבון עם מזהה דומיין של דומיין שבבעלותכם או בשליטתכם. כך תוכלו לוודא שסוג החשבון יהיה ייחודי.
|
לסוג חשבון שמציע נתונים של אנשי קשר בדרך כלל משויך מתאם סנכרון מסתנכרן עם ספק אנשי הקשר. |
DELETED
|
העמודה 'נמחקה' של איש קשר גולמי. | הדגל הזה מאפשר לספק אנשי הקשר לשמור את השורה באופן פנימי עד שהמתאמים לסנכרון יוכלו למחוק את השורה מהשרתים שלהם, ואז למחוק את השורה מהמאגר. |
הערות
הנה הערות חשובות בנושא
טבלה של ContactsContract.RawContacts
:
-
שם גולמי של איש קשר לא נשמר בשורה שלו
ContactsContract.RawContacts
במקום זאת, הטבלהContactsContract.Data
,ContactsContract.CommonDataKinds.StructuredName
שורה. לאיש קשר גולמי יש רק שורה אחת מהסוג הזה בטבלהContactsContract.Data
. -
זהירות: כדי להשתמש בנתוני החשבון שלכם בשורה של איש קשר גולמי, קודם צריך לרשום אותם ב-
AccountManager
. כדי לעשות את זה, צריך כדי להוסיף לרשימת החשבונות את סוג החשבון ואת שם החשבון שלהם. אם לא תעשו זאת, ספק אנשי הקשר ימחק באופן אוטומטי את שורת אנשי הקשר הגולמיים.לדוגמה, אם רוצים שהאפליקציה תשמור את נתוני אנשי הקשר של השירות מבוסס-האינטרנט. עם הדומיין
com.example.dataservice
, ועם חשבון המשתמש עבור השירות שלךbecky.sharp@dataservice.example.com
, תחילה המשתמש צריך להוסיף את החשבון 'type' (com.example.dataservice
) והחשבון 'name' (becky.smart@dataservice.example.com
) לפני שהאפליקציה תוכל להוסיף שורות גולמיות של אנשי קשר. אפשר להסביר את הדרישה הזו למשתמש במסמכי העזרה, או לבקש מהמשתמש להוסיף את הסוג והשם, או את שניהם. סוגי חשבונות ושמות חשבונות מתוארים בפירוט בקטע הבא.
מקורות של נתונים גולמיים של אנשי קשר
כדי להבין איך פועלים אנשי הקשר הגולמיים, אפשר להתייחס למשתמש "אמילי דיקינסון" שיש להם את הפרטים הבאים שלושה חשבונות משתמשים שהוגדרו במכשיר שלה:
emily.dickinson@gmail.com
emilyd@gmail.com
- חשבון Twitter 'belle_of_amherst'
משתמש זה הפעיל את האפשרות סנכרון אנשי קשר בכל שלושת החשבונות האלה ב הגדרות חשבונות.
נניח ש-Emily Dickinson פותחת חלון דפדפן, נכנסת ל-Gmail בתור emily.dickinson@gmail.com
, פותחת את אנשי הקשר ומוסיפה את Thomas Higginson. בהמשך, היא מתחברת ל-Gmail בתור emilyd@gmail.com
ושולחת אימייל אל 'Thomas Higginson', וכך הוא מתווסף באופן אוטומטי כאיש קשר. היא גם עוקבת אחרי 'colonel_tom' (מזהה Twitter של Thomas Higginson) ב-Twitter.
ספק אנשי הקשר יוצר שלושה אנשי קשר גולמיים כתוצאה מכך:
-
איש קשר גולמי של "תומס היגינסון" שמשויך אל
emily.dickinson@gmail.com
. סוג חשבון המשתמש הוא Google. -
איש קשר גולמי שני של 'Thomas Higginson' שמשויך ל-
emilyd@gmail.com
. סוג חשבון המשתמש הוא גם Google. יש איש קשר גולמי שני, למרות שהשם זהה לשם קודם, כי האדם נוסף לחשבון משתמש אחר. - איש קשר גולמי שלישי של "תומס היגינסון" המשויך ל-"belle_of_amherst". המשתמש/ת סוג החשבון הוא Twitter.
נתונים
כפי שצוין קודם, הנתונים של איש קשר גולמי מאוחסנים בשורה ContactsContract.Data
שמקושרת לערך _ID
של איש הקשר הגולמי. כך יכולים להיות כמה מופעים של אותו איש קשר גולמי אחד
סוג הנתונים, כמו כתובות אימייל או מספרי טלפון. לדוגמה, אם ל-'Thomas Higginson' ב-emilyd@gmail.com
(שורת איש הקשר הגולמי של Thomas Higginson שמשויכת לחשבון Google emilyd@gmail.com
) יש כתובת אימייל ביתית thigg@gmail.com
וכתובת אימייל לעבודה thomas.higginson@gmail.com
, ספק אנשי הקשר שומר את שתי השורות של כתובות האימייל ומקשר את שתיהן לאיש הקשר הגולמי.
שימו לב שבטבלה היחידה הזו מאוחסנים סוגים שונים של נתונים. השורות של שם התצוגה, מספר הטלפון, האימייל, הכתובת, התמונה ופרטי האתר נמצאות בטבלה ContactsContract.Data
. כדי לעזור לנהל את המצב,
בטבלה ContactsContract.Data
יש כמה עמודות עם שמות תיאוריים.
ועוד שמות כלליים. לתוכן של עמודת שם תיאורי יש משמעות זהה
ללא קשר לסוג הנתונים שבשורה, בעוד שהתוכן של עמודת שם גנרי
משמעויות שונות בהתאם לסוג הנתונים.
שמות תיאוריים של עמודות
דוגמאות לשמות תיאוריים של עמודות:
-
RAW_CONTACT_ID
-
הערך של העמודה
_ID
של איש הקשר הגולמי לנתונים האלה. -
MIMETYPE
-
סוג הנתונים שמאוחסנים בשורה הזו, מבוטאת כסוג MIME מותאם אישית. ספק אנשי הקשר משתמש בסוגי ה-MIME שמוגדרים בתת-הסוגים של
ContactsContract.CommonDataKinds
. סוגי ה-MIME האלה הם קוד פתוח, וכל אפליקציה או מתאם סנכרון שפועלים עם ספק אנשי הקשר יכולים להשתמש בהם. -
IS_PRIMARY
-
אם שורת נתונים מהסוג הזה יכולה להופיע יותר מפעם אחת לגבי איש קשר גולמי,
IS_PRIMARY
דגלי עמודות שורת הנתונים שמכילה את הנתונים הראשיים של הסוג. לדוגמה, אם המשתמש לוחץ לחיצה ארוכה על מספר טלפון של איש קשר ובוחר באפשרות הגדרת ברירת מחדל, בעמודהIS_PRIMARY
של השורהContactsContract.Data
שמכילה את המספר הזה יוגדר ערך שאינו אפס.
שמות עמודות כלליים
יש 15 עמודות כלליות בשמות DATA1
עד DATA15
שזמינות לכולם, ועוד ארבע עמודות כלליות בשמות SYNC1
עד SYNC4
שרק מתאמי סנכרון יכולים להשתמש בהן. הקבועים הכלליים של שמות עמודות תמיד פועלים, ללא קשר לסוג של
נתונים שהשורה כוללת.
העמודה DATA1
נוספה לאינדקס. ספק אנשי הקשר תמיד משתמש בעמודה הזו לצורך
הנתונים שהספק מצפה שיהיו היעד התדיר ביותר של השאילתה. לדוגמה, בשורה של כתובת אימייל, העמודה הזו מכילה את כתובת האימייל בפועל.
לפי המוסכמה, העמודה DATA15
שמורה לאחסון אובייקט בינארי גדול (Binary Large Object)
נתוני (BLOB) כגון תמונות ממוזערות של תמונות.
שמות עמודות ספציפיים לסוג
כדי להקל על העבודה עם העמודות של סוג מסוים של שורה, ספק אנשי הקשר מספק גם קבועים של שמות עמודות ספציפיים לסוג, שמוגדרים בתת-כיתות של ContactsContract.CommonDataKinds
. הקבועים נותנים פשוט שם קבוע שונה לאותו שם עמודה, כדי לעזור לכם לגשת לנתונים בשורה של סוג מסוים.
לדוגמה, המחלקה ContactsContract.CommonDataKinds.Email
מגדירה
קבועי שמות של עמודות לפי סוג בשורה ContactsContract.Data
הוא מסוג MIME
Email.CONTENT_ITEM_TYPE
. הכיתה מכילה את הקבוע ADDRESS
לעמודה של כתובת האימייל. הערך בפועל של ADDRESS
הוא 'data1', שהוא זהה לשם הגנרי של העמודה.
זהירות: אל תוסיפו נתונים מותאמים אישית משלכם אל
הטבלה ContactsContract.Data
מכילה שורה שכוללת אחד
סוגי MIME המוגדרים מראש של הספק. אם תעשו זאת, אתם עלולים לאבד את הנתונים או לגרום לספק
תקלה. לדוגמה, אין להוסיף שורה עם סוג MIME
Email.CONTENT_ITEM_TYPE
שמכיל שם משתמש במקום כתובת אימייל
עמודה DATA1
. אם השתמשת בסוג MIME מותאם אישית לשורה, השימוש שלך בחינם
כדי להגדיר שמות עמודות ספציפיים לסוג מסוים ולהשתמש בעמודות בכל אופן שתרצו.
איור 2 מציג כיצד עמודות תיאוריות ועמודות נתונים מופיעות
שורה אחת (ContactsContract.Data
) והשמות של עמודות ספציפיות לסוג "overlay"
שמות העמודות הגנריים

איור 2. שמות עמודות ספציפיים לסוג ושמות עמודות כלליים.
כיתות של שמות עמודות ספציפיות לסוג
טבלה 2 מפרטת את סיווגי השמות הנפוצים ביותר של עמודות לפי סוג:
טבלה 2. כיתות של שמות עמודות ספציפיות לסוג
שיעור מיפוי | סוג הנתונים | הערות |
---|---|---|
ContactsContract.CommonDataKinds.StructuredName |
נתוני השם של איש הקשר הגולמי שמשויך לשורת הנתונים הזו. | איש קשר גולמי כולל רק אחת מהשורות האלה. |
ContactsContract.CommonDataKinds.Photo |
התמונה הראשית של איש הקשר הגולמי שמשויך לשורת הנתונים הזו. | איש קשר גולמי כולל רק אחת מהשורות האלה. |
ContactsContract.CommonDataKinds.Email |
כתובת אימייל של איש הקשר הגולמי המשויך לשורת הנתונים הזו. | לאיש קשר גולמי יכולות להיות מספר כתובות אימייל. |
ContactsContract.CommonDataKinds.StructuredPostal |
כתובת למשלוח דואר של איש הקשר הגולמי המשויך לשורת הנתונים הזו. | לאיש קשר גולמי יכולות להיות כמה כתובות למשלוח דואר. |
ContactsContract.CommonDataKinds.GroupMembership |
מזהה שמקשר את איש הקשר הגולמי לאחת מהקבוצות בספק אנשי הקשר. | קבוצות הן תכונה אופציונלית של סוג חשבון ושם חשבון. הם מתוארים ב תוכלו למצוא פרטים נוספים בקטע קבוצות של אנשי קשר. |
אנשי קשר
הספק של אנשי הקשר משליך את שורות אנשי הקשר הגולמיות מכל סוגי החשבונות ומכל שמות החשבונות כדי ליצור איש קשר. כך קל יותר להציג ולשנות את כל הנתונים שהמשתמש אסף לגבי אדם מסוים. שירות ניהול אנשי הקשר מנהל את היצירה של שורות אנשי קשר חדשות ואת הצבירה של אנשי קשר גולמיים בשורה קיימת של איש קשר. לא אפליקציות ולא מתאמי סנכרון מורשים להוסיף אנשי קשר, ועמודות מסוימות בשורת אנשי קשר מוגדרות לקריאה בלבד.
הערה: אם תנסו להוסיף איש קשר לספק אנשי הקשר עם insert()
, תקבלו חריגה מסוג UnsupportedOperationException
. אם תנסו לעדכן עמודה שמופיעה בתור 'לקריאה בלבד', המערכת תתעלם מהעדכון.
ספק אנשי הקשר יוצר איש קשר חדש בתגובה להוספה של איש קשר גולמי חדש שלא תואם לאף איש קשר קיים. הספק עושה זאת גם אם נתוני RAW קיימים הנתונים של איש הקשר משתנים כך שאיש הקשר כבר אינו תואם את איש הקשר מצורף בעבר. אם אפליקציה או מתאם סנכרון יוצרים איש קשר חדש בפורמט גולמי שתואם לאיש קשר קיים, איש הקשר החדש בפורמט גולמי יתווסף לאיש הקשר הקיים.
ספק אנשי הקשר מקשר שורה של איש קשר לשורות של אנשי הקשר הגולמיות עם השורה של איש הקשר
העמודה _ID
בContacts
טבלה. העמודה CONTACT_ID
בטבלת אנשי הקשר הגולמיים ContactsContract.RawContacts
מכילה ערכים של _ID
בשביל שורת אנשי הקשר שמשויכת לכל שורה של אנשי קשר גולמיים.
הטבלה ContactsContract.Contacts
כוללת גם את העמודה
LOOKUP_KEY
שהוא
'קבוע' לקישור לשורת אנשי הקשר. מכיוון שספק אנשי הקשר שומר על אנשי הקשר באופן אוטומטי, הוא עשוי לשנות את הערך של _ID
בשורה של איש הקשר בתגובה לאיסוף או לסנכרון. גם אם זה יקרה, ה-URI של התוכן CONTENT_LOOKUP_URI
בשילוב עם LOOKUP_KEY
של איש הקשר עדיין יצביע על שורת איש הקשר, כך שתוכלו להשתמש ב-LOOKUP_KEY
כדי לשמור על קישורים לאנשי קשר 'מועדפים' וכן הלאה. לעמודה הזאת יש פורמט משלה
לא קשורים לפורמט של העמודה _ID
.
איור 3 מציג את הקשרים בין שלוש הטבלאות הראשיות.

איור 3. היחסים בין טבלאות Contacts, Raw Contacts ו-Details.
זהירות: אם אתם מפרסמים את האפליקציה בחנות Google Play, או אם האפליקציה מותקנת במכשיר שמותקנת בו גרסת Android 10 (API ברמה 29) ואילך, חשוב לזכור שקבוצה מוגבלת של שדות ושיטות נתונים של אנשי קשר הם מיושנים.
בתנאים שצוינו, המערכת מנקה מדי פעם את הערכים שנכתבו בשדות הנתונים האלה:
-
ContactsContract.ContactOptionsColumns.LAST_TIME_CONTACTED
-
ContactsContract.ContactOptionsColumns.TIMES_CONTACTED
-
ContactsContract.DataUsageStatColumns.LAST_TIME_USED
-
ContactsContract.DataUsageStatColumns.TIMES_USED
גם ממשקי ה-API שמשמשים להגדרת שדות הנתונים שלמעלה לא תקפים יותר:
בנוסף, השדות הבאים לא מחזירים יותר אנשי קשר תדירים. חשוב לזכור שחלק מהשדות האלה משפיעים על הדירוג של אנשי הקשר רק אם אנשי הקשר הם חלק מסוג נתונים ספציפי.
-
ContactsContract.Contacts.CONTENT_FREQUENT_URI
-
ContactsContract.Contacts.CONTENT_STREQUENT_URI
-
ContactsContract.Contacts.CONTENT_STREQUENT_FILTER_URI
-
CONTENT_FILTER_URI
(משפיע רק על סוגי הנתונים אימייל, טלפון, ניתן להתקשר ואנשי קשר) -
ENTERPRISE_CONTENT_FILTER_URI
(משפיע רק על סוגי הנתונים Email, Phone ו-Callable)
אם האפליקציות שלך ניגשות לשדות או לממשקי ה-API האלה או מעדכנת אותם, יש להשתמש בשיטה שיטות. לדוגמה, אפשר לעמוד בתנאי של תרחישי שימוש מסוימים באמצעות ספקי תוכן פרטיים או נתונים אחרים שמאוחסנים באפליקציה או במערכות הקצה העורפי.
כדי לוודא שהפונקציונליות של האפליקציה לא מושפעת מהשינוי הזה, תוכלו לנקות את שדות הנתונים האלה באופן ידני. כדי לעשות זאת, מריצים את ה-ADB הבא פקודה במכשיר שמותקנת בו גרסת Android 4.1 (רמת API 16) ומעלה:
adb shell content delete \ --uri content://com.android.contacts/contacts/delete_usage
נתונים ממתאמי סנכרון
המשתמשים מזינים את פרטי אנשי הקשר ישירות במכשיר, אבל הנתונים עוברים גם לספק אנשי הקשר משירותי אינטרנט באמצעות מתאמי סנכרון, שמבצעים באופן אוטומטי את העברת הנתונים בין המכשיר לשירותים. המתאמים לסנכרון פועלים ברקע
בשליטת המערכת, והם קוראים לשיטות ContentResolver
לניהול נתונים.
ב-Android, שירות האינטרנט שאיתו פועל מתאם הסנכרון מזוהה לפי סוג החשבון. כל מתאם סנכרון פועל עם סוג חשבון אחד, אבל הוא יכול לתמוך בשמות של חשבונות מרובים עבור מהסוג הזה. סוגים של חשבונות ושמות של חשבונות מתוארים בקצרה בקטע מקורות של נתוני אנשי קשר גולמיים. ההגדרות הבאות מציעות בצורה מפורטת יותר, ולתאר את הקשר בין סוג החשבון והשם של מתאמים ושירותים לסנכרון.
- סוג חשבון
-
מזהה שירות שבו המשתמש אחסן נתונים. בדרך כלל, המשתמש צריך
לבצע אימות באמצעות השירות. לדוגמה, אנשי הקשר ב-Google הם סוג חשבון שמזוהה באמצעות הקוד
google.com
. הערך הזה תואם לסוג החשבון שבו משתמשיםAccountManager
- שם החשבון
- מזהה חשבון או כניסה ספציפיים לסוג חשבון. חשבונות אנשי קשר מחשבון Google הם זהים לחשבונות Google עם כתובת אימייל כשם החשבון. שירותים אחרים עשויים להשתמש בשם משתמש בן מילה אחת או במזהה מספרי.
סוגים של חשבונות לא חייבים להיות ייחודיים. משתמש יכול להגדיר כמה חשבונות של אנשי קשר בחשבון Google ולהוריד את הנתונים שלהם לספק אנשי הקשר; מצב כזה יכול לקרות אם למשתמש יש קבוצה אחת של אנשי קשר אישיים לשם חשבון אישי, וקבוצה נוספת לעבודה. שמות החשבונות הם בדרך כלל ייחודיות. יחד, הם מזהים תעבורת נתונים ספציפית בין ספק אנשי הקשר לבין שירות חיצוני.
אם אתם רוצים להעביר את הנתונים של השירות שלכם לספק אנשי הקשר, תצטרכו לכתוב מתאם סנכרון משלכם. הנושא הזה מוסבר בפירוט בקטע מתאמי סנכרון של ספקי אנשי קשר.
באיור 4 מוצגת ההתאמה של ספק אנשי הקשר לזרימת הנתונים על אנשים. בתיבה 'מתאמי סנכרון', כל מתאם מסומן לפי סוג החשבון שלו.

איור 4. תהליך העברת הנתונים של 'ניהול אנשי הקשר'.
הרשאות נדרשות
אפליקציות שרוצות לגשת לספק אנשי הקשר חייבות לבקש את הפרטים הבאים הרשאות:
- הרשאת קריאה לטבלה אחת או יותר
-
READ_CONTACTS
, מצוין בAndroidManifest.xml
עם רכיב<uses-permission>
בתור<uses-permission android:name="android.permission.READ_CONTACTS">
- הרשאת כתיבה לטבלה אחת או יותר
-
WRITE_CONTACTS
, שצוין ב-AndroidManifest.xml
עם רכיב<uses-permission>
בתור<uses-permission android:name="android.permission.WRITE_CONTACTS">
.
ההרשאות האלה לא חלות על הנתונים בפרופיל המשתמש. פרופיל המשתמש והתוכן שלו ההרשאות הנדרשות מתוארות בקטע הבא, פרופיל המשתמש.
חשוב לזכור שהנתונים של אנשי הקשר של המשתמש הם אישיים ורגישים. המשתמשים חוששים הפרטיות שלהם, ולכן הם לא רוצים שאפליקציות יאספו נתונים עליהם או על אנשי הקשר שלהם. אם לא ברור למה נדרשת הרשאה כדי לגשת לנתונים של אנשי הקשר, הם עשויים לתת האפליקציה שלך קיבלה דירוג נמוך או פשוט מסרבת להתקין אותה.
פרופיל המשתמש
הטבלה ContactsContract.Contacts
כוללת שורה אחת שמכילה
של המשתמש במכשיר. בנתונים האלה מתואר user
של המכשיר
מאנשי הקשר של המשתמש. השורה של אנשי הקשר בפרופיל מקושרת לשורה של אנשי קשר גולמיים בכל מערכת שמשתמשת בפרופיל.
כל שורה גולמית של איש קשר של פרופיל יכולה לכלול מספר שורות נתונים. תנאים קבועים לגישה למשתמש
זמינים בכיתה ContactsContract.Profile
.
כדי לגשת לפרופיל המשתמש נדרשות הרשאות מיוחדות. בנוסף להרשאות READ_CONTACTS
ו-WRITE_CONTACTS
שנדרשות לקריאה ולכתיבה, כדי לגשת לפרופיל המשתמש נדרשות ההרשאות android.Manifest.permission#READ_PROFILE ו-android.Manifest.permission#WRITE_PROFILE לקריאה ולכתיבה, בהתאמה.
חשוב לזכור שפרופיל של משתמש נחשב כמידע אישי רגיש. ההרשאה android.Manifest.permission#READ_PROFILE מאפשרת לך לגשת אל נתונים שמאפשרים זיהוי אישי. צריך להסביר למשתמשים למה נדרשות הרשאות גישה לפרופיל המשתמש בתיאור האפליקציה.
כדי לאחזר את שורת איש הקשר שמכילה את הפרופיל של המשתמש, צריך להפעיל את הפונקציה ContentResolver.query()
. הגדרת ה-URI של התוכן כ-
CONTENT_URI
ולא מספקים
קריטריונים לבחירה. ניתן גם להשתמש ב-URI של תוכן זה בתור ה-URI הבסיסי לאחזור גולמיים
אנשי הקשר או הנתונים של הפרופיל. לדוגמה, קטע הקוד הבא מאחזר נתונים עבור הפרופיל:
Kotlin
// Sets the columns to retrieve for the user profile projection = arrayOf( ContactsContract.Profile._ID, ContactsContract.Profile.DISPLAY_NAME_PRIMARY, ContactsContract.Profile.LOOKUP_KEY, ContactsContract.Profile.PHOTO_THUMBNAIL_URI ) // Retrieves the profile from the Contacts Provider profileCursor = contentResolver.query( ContactsContract.Profile.CONTENT_URI, projection, null, null, null )
Java
// Sets the columns to retrieve for the user profile projection = new String[] { Profile._ID, Profile.DISPLAY_NAME_PRIMARY, Profile.LOOKUP_KEY, Profile.PHOTO_THUMBNAIL_URI }; // Retrieves the profile from the Contacts Provider profileCursor = getContentResolver().query( Profile.CONTENT_URI, projection , null, null, null);
הערה: אם מאחזרים כמה שורות של אנשי קשר ורוצים לבדוק אם אחת מהן
הוא פרופיל המשתמש, צריך לבדוק את השורה
עמודה IS_USER_PROFILE
. העמודה הזו
מוגדר כ-'1' אם איש הקשר הוא פרופיל המשתמש.
מטא-נתונים של ניהול אנשי הקשר
ספק אנשי הקשר מנהל נתונים שעוקבים אחרי המצב של נתוני אנשי הקשר בחשבון
של מאגר הנתונים. המטא-נתונים האלה לגבי המאגר מאוחסנים במקומות שונים, כולל השורות בטבלאות Raw Contacts, Data ו-Contacts, בטבלה ContactsContract.Settings
ובטבלה ContactsContract.SyncState
. הטבלה הבאה מציגה את
ההשפעה של כל אחד מקטעי המטא-נתונים האלה:
טבלה 3 מטא-נתונים בספק אנשי הקשר
טבלה | עמודה | ערכים | משמעות |
---|---|---|---|
ContactsContract.RawContacts |
DIRTY |
'0' – לא השתנה מאז הסנכרון האחרון. |
סימון של אנשי קשר גולמיים שהשתנו במכשיר וצריכים להסתנכרן חזרה עם השרת. הערך מוגדר באופן אוטומטי על ידי ספק אנשי הקשר ב-Android
מתעדכנות שורה.
מתאמי סנכרון שמשנים את הנתונים הגולמיים של אנשי הקשר או טבלאות הנתונים תמיד צריכים להוסיף
מחרוזת |
'1' – השתנה מאז הסנכרון האחרון, צריך לסנכרן אותו חזרה לשרת. | |||
ContactsContract.RawContacts |
VERSION |
מספר הגרסה של השורה הזו. | 'ספק אנשי הקשר' מגדיל את הערך הזה באופן אוטומטי בכל פעם שהשורה או שינויים בנתונים שקשורים אליו. |
ContactsContract.Data |
DATA_VERSION |
מספר הגרסה של השורה הזו. | 'ספק אנשי הקשר' מגדיל את הערך הזה באופן אוטומטי בכל פעם ששורת הנתונים משתנה. |
ContactsContract.RawContacts |
SOURCE_ID |
ערך מחרוזת שמזהה באופן ייחודי את איש הקשר הגולמי הזה עם החשבון שבה הוא נוצר. |
כשמתאם סנכרון יוצר איש קשר חדש בפורמט גולמי, צריך להגדיר בעמודה הזו את המזהה הייחודי של איש הקשר בפורמט גולמי בשרת. כשאפליקציה ל-Android יוצרת אפליקציה חדשה
איש קשר גולמי, האפליקציה צריכה להשאיר את העמודה הזו ריקה. הפעולה הזו מאותתת למתאם הסנכרון שהוא צריך ליצור איש קשר חדש בפורמט גולמי בשרת ולקבל ערך בשדה SOURCE_ID .
באופן ספציפי, מזהה המקור חייב להיות ייחודי לכל חשבון מסוג והוא צריך להיות יציב בכל סנכרונים:
|
ContactsContract.Groups |
GROUP_VISIBLE |
'0' – אנשי הקשר בקבוצה הזו לא אמורים להיות גלויים בממשקי המשתמש של אפליקציות ל-Android. | העמודה הזו מיועדת לתאימות לשרתים שמאפשרים למשתמש להסתיר אנשי קשר קבוצות מסוימות. |
'1' - אנשי הקשר בקבוצה הזו יכולים להופיע בממשקי המשתמש של האפליקציה. | |||
ContactsContract.Settings |
UNGROUPED_VISIBLE |
'0' – בחשבון הזה ובסוג החשבון הזה, אנשי קשר שלא שייכים לקבוצה לא גלויים לממשקי המשתמש של אפליקציות ל-Android. |
כברירת מחדל, אנשי קשר לא גלויים אם אף אחד מאנשי הקשר הגולמיים שלהם לא שייך לקבוצה (השתייכות לקבוצה של איש קשר גולמי מסומן בשורה אחת או יותר של ContactsContract.CommonDataKinds.GroupMembership בטבלה ContactsContract.Data ).
על ידי הגדרת הדגל הזה בשורה ContactsContract.Settings בטבלה
עבור סוג חשבון וחשבון, ניתן לאלץ אנשי קשר ללא קבוצות להיות גלויים.
אחת מהשימושים בדגל הזה היא להציג אנשי קשר משרתי אימייל שלא משתמשים בקבוצות.
|
'1' – בחשבון הזה ובסוג החשבון הזה, אנשי קשר שלא שייכים לקבוצה גלויים לממשקי המשתמש של האפליקציות. | |||
ContactsContract.SyncState |
(הכול) | אפשר להשתמש בטבלה הזו כדי לאחסן מטא-נתונים של מתאם הסנכרון. | בעזרת הטבלה הזו ניתן לאחסן באופן קבוע את מצב הסנכרון ונתונים אחרים שקשורים לסנכרון במכשיר. |
גישת ספק לאנשי הקשר
בקטע הזה מפורטות הנחיות לגישה לנתונים מספק אנשי הקשר, עם דגש על הנושאים הבאים:
- שאילתות על ישויות.
- שינוי קבוצתי.
- אחזור ושינוי של כוונות.
- תקינות הנתונים.
אפשר לקרוא מידע נוסף על ביצוע שינויים באמצעות מתאם סנכרון בקטע מתאמי סנכרון של ספקי אנשי קשר.
ישויות שליחת שאילתות
בגלל שהטבלאות של 'ספקי אנשי קשר' מאורגנות בהיררכיה, מומלץ בדרך כלל
מאחזרים שורה ואת כל הנתונים של 'child'. השורות שמקושרות אליו. לדוגמה, כדי להציג
את כל המידע עבור אדם, ייתכן שתרצו לאחזר את כל הנתונים
ContactsContract.RawContacts
שורות לפריט יחיד
שורה אחת (ContactsContract.Contacts
) או כל
ContactsContract.CommonDataKinds.Email
שורות לפריט יחיד
שורה ContactsContract.RawContacts
. כדי לאפשר זאת, ספק אנשי הקשר מציע מבנים של ישויות, שמשמשים כאיחודים של מסדי נתונים בין טבלאות.
ישות היא כמו טבלה המורכבת מעמודות שנבחרו מטבלת הורה ומהטבלה הצאצאית שלה.
כשמריצים שאילתה על ישות, צריך לספק תחזית וקריטריונים לחיפוש על סמך העמודות
זמינים מהישות. התוצאה היא Cursor
שמכיל
שורה אחת לכל שורה של טבלת צאצא שאוחזרה. לדוגמה, אם שולחים שאילתה ל-ContactsContract.Contacts.Entity
עם שם של איש קשר וכל השורות של ContactsContract.CommonDataKinds.Email
עם כל אנשי הקשר הגולמיים של השם הזה, מקבלים חזרה Cursor
שמכיל שורה אחת לכל שורה של ContactsContract.CommonDataKinds.Email
.
ישויות מפשטות את השאילתות. באמצעות ישות, ניתן לאחזר את כל נתוני אנשי הקשר של איש קשר או איש קשר גולמי בו-זמנית, במקום שתצטרכו לבדוק קודם את טבלת ההורה כדי לקבל מזהה, ואז צריך להריץ שאילתה בטבלת הצאצא עם המזהה הזה. כמו כן, ספק אנשי הקשר מעבד שאילתה כנגד ישות בעסקה אחת, המבטיחה שהנתונים המאוחזרים עקביות באופן פנימי.
הערה: בדרך כלל ישות לא מכילה את כל העמודות של טבלת ההורה וטבלת הצאצא. אם מנסים לעבוד עם שם עמודה שלא מופיע ברשימת הקבועים של שמות העמודות של הישות, מופיעה הערך Exception
.
קטע הקוד הבא מראה איך לאחזר את כל שורות איש הקשר הגולמיות של איש קשר. קטע הקוד
חלק מיישום גדול יותר שכולל שתי פעילויות, "העיקרית" ו'פירוט'. הפעילות העיקרית
מציגה רשימה של שורות אנשי קשר. כשהמשתמש יבחר אחת, הפעילות תשלח את המזהה שלה לפרטים
פעילות. הפעילות המפורטות משתמשת בContactsContract.Contacts.Entity
כדי להציג את כל שורות הנתונים מכל אנשי הקשר הגולמיים המשויכים
איש קשר.
קטע הקוד הזה נלקח מהפעילות 'פרטים':
Kotlin
... /* * Appends the entity path to the URI. In the case of the Contacts Provider, the * expected URI is content://com.google.contacts/#/entity (# is the ID value). */ contactUri = Uri.withAppendedPath( contactUri, ContactsContract.Contacts.Entity.CONTENT_DIRECTORY ) // Initializes the loader identified by LOADER_ID. loaderManager.initLoader( LOADER_ID, // The identifier of the loader to initialize null, // Arguments for the loader (in this case, none) this // The context of the activity ) // Creates a new cursor adapter to attach to the list view cursorAdapter = SimpleCursorAdapter( this, // the context of the activity R.layout.detail_list_item, // the view item containing the detail widgets mCursor, // the backing cursor fromColumns, // the columns in the cursor that provide the data toViews, // the views in the view item that display the data 0) // flags // Sets the ListView's backing adapter. rawContactList.adapter = cursorAdapter ... override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> { /* * Sets the columns to retrieve. * RAW_CONTACT_ID is included to identify the raw contact associated with the data row. * DATA1 contains the first column in the data row (usually the most important one). * MIMETYPE indicates the type of data in the data row. */ val projection: Array<String> = arrayOf( ContactsContract.Contacts.Entity.RAW_CONTACT_ID, ContactsContract.Contacts.Entity.DATA1, ContactsContract.Contacts.Entity.MIMETYPE ) /* * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw * contact collated together. */ val sortOrder = "${ContactsContract.Contacts.Entity.RAW_CONTACT_ID} ASC" /* * Returns a new CursorLoader. The arguments are similar to * ContentResolver.query(), except for the Context argument, which supplies the location of * the ContentResolver to use. */ return CursorLoader( applicationContext, // The activity's context contactUri, // The entity content URI for a single contact projection, // The columns to retrieve null, // Retrieve all the raw contacts and their data rows. null, // sortOrder // Sort by the raw contact ID. ) }
Java
... /* * Appends the entity path to the URI. In the case of the Contacts Provider, the * expected URI is content://com.google.contacts/#/entity (# is the ID value). */ contactUri = Uri.withAppendedPath( contactUri, ContactsContract.Contacts.Entity.CONTENT_DIRECTORY); // Initializes the loader identified by LOADER_ID. getLoaderManager().initLoader( LOADER_ID, // The identifier of the loader to initialize null, // Arguments for the loader (in this case, none) this); // The context of the activity // Creates a new cursor adapter to attach to the list view cursorAdapter = new SimpleCursorAdapter( this, // the context of the activity R.layout.detail_list_item, // the view item containing the detail widgets mCursor, // the backing cursor fromColumns, // the columns in the cursor that provide the data toViews, // the views in the view item that display the data 0); // flags // Sets the ListView's backing adapter. rawContactList.setAdapter(cursorAdapter); ... @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { /* * Sets the columns to retrieve. * RAW_CONTACT_ID is included to identify the raw contact associated with the data row. * DATA1 contains the first column in the data row (usually the most important one). * MIMETYPE indicates the type of data in the data row. */ String[] projection = { ContactsContract.Contacts.Entity.RAW_CONTACT_ID, ContactsContract.Contacts.Entity.DATA1, ContactsContract.Contacts.Entity.MIMETYPE }; /* * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw * contact collated together. */ String sortOrder = ContactsContract.Contacts.Entity.RAW_CONTACT_ID + " ASC"; /* * Returns a new CursorLoader. The arguments are similar to * ContentResolver.query(), except for the Context argument, which supplies the location of * the ContentResolver to use. */ return new CursorLoader( getApplicationContext(), // The activity's context contactUri, // The entity content URI for a single contact projection, // The columns to retrieve null, // Retrieve all the raw contacts and their data rows. null, // sortOrder); // Sort by the raw contact ID. }
כשהטעינה תסתיים, תתבצע קריאה חוזרת (callback) של LoaderManager
אל
onLoadFinished()
. אחד מהארגומנטים הנכנסים לשיטה הזו הוא Cursor
עם תוצאות השאילתה. באפליקציה שלכם אפשר לקבל את
נתונים מהCursor
הזה כדי להציג אותו או כדי להמשיך לעבוד איתו.
שינוי של מספר פריטים בו-זמנית
כשאפשר, כדאי להוסיף, לעדכן ולמחוק נתונים ב'ספק אנשי הקשר' ב
'מצב אצווה', על ידי יצירת ArrayList
של
ContentProviderOperation
אובייקטים ושיחות
applyBatch()
. כי
ספק אנשי הקשר מבצע את כל הפעולות
applyBatch()
בסינגל
טרנזקציה, השינויים שלך אף פעם לא ישאירו את מאגר אנשי הקשר
. שינוי בכמות גדולה מאפשר גם להוסיף בו-זמנית איש קשר בסיסי ואת פרטיו המפורטים.
הערה: כדי לשנות איש קשר גולמי יחיד, מומלץ לשלוח כוונה (intent) לאפליקציית אנשי הקשר של המכשיר במקום לטפל בשינוי באפליקציה שלכם. אפשר לקרוא הסבר מפורט יותר בקטע אחזור ושינוי באמצעות כוונות.
נקודות עצירה
שינוי באצווה שמכיל מספר גדול של פעולות עלול לחסום תהליכים אחרים, וכתוצאה מכך חוויית המשתמש הכוללת תהיה גרועה. כדי לארגן את כל השינויים שרוצים
בכמה שפחות רשימות נפרדות, ובו-זמנית למנוע אותן
וחסימת המערכת, עליך להגדיר נקודות תפוקה לפעולה אחת או יותר.
נקודת תפוקה היא אובייקט ContentProviderOperation
שקיבל
הערך של isYieldAllowed()
הוגדר כ-
true
. כשהספק של אנשי הקשר נתקל בנקודת תפוקה, הוא משהה את העבודה עד
מאפשרים לתהליכים אחרים להריץ את העסקה הנוכחית וסוגרים את העסקה. כשהספק יתחיל לפעול שוב,
ממשיך בפעולה הבאה ב-ArrayList
ומתחילה פעולה חדשה
העסקה.
נקודות התשואה כן מניבות יותר מעסקה אחת לכל קריאה ל-applyBatch()
. בגלל
לכן צריך להגדיר נקודת תפוקה לפעולה האחרונה עבור קבוצה של שורות קשורות.
לדוגמה, צריך להגדיר נקודת יעד לפעולה האחרונה בקבוצה שמוסיפה שורות של אנשי קשר גולמיים ושורות הנתונים המשויכות שלהם, או לפעולה האחרונה בקבוצת שורות שקשורות לאיש קשר יחיד.
נקודות עצירה הן גם יחידה של פעולה אטומית. כל הגישה בין שתי נקודות תשואה תצליח או תיכשל כיחידה אחת. אם לא מגדירים נקודות ייצור, הפעולה האטומית הקטנה ביותר היא כל קבוצת הפעולות. אם בכל זאת משתמשים בנקודות תפוקה, מפני ירידה בביצועי המערכת, ובו-זמנית להבטיח שתת-קבוצה של הוא אטומי.
שינוי הפניות קודמות
כשמוסיפים שורה גולמית חדשה של איש קשר ואת שורות הנתונים שמשויכות אליה, כקבוצה של
ContentProviderOperation
אובייקטים, יש לקשר את שורות הנתונים אל
את שורת איש הקשר הגולמית על ידי הוספת נתוני איש הקשר הגולמיים
ערך של _ID
בתור
ערך RAW_CONTACT_ID
. עם זאת, הערך הזה לא זמין כשיוצרים את ContentProviderOperation
בשורה של הנתונים, כי עדיין לא החילו את ContentProviderOperation
על שורת איש הקשר הגולמי. כדי לעקוף את הבעיה,
למחלקה ContentProviderOperation.Builder
יש את ה-method
withValueBackReference()
.
השיטה הזו מאפשרת להוסיף או לשנות עמודה עם התוצאה של פעולה קודמת.
withValueBackReference()
ל-method יש שני ארגומנטים:
-
key
- המפתח של צמד מפתח/ערך. הערך של הארגומנט הזה צריך להיות שם של עמודה בטבלה שאתם משנים.
-
previousResult
-
האינדקס שמתחיל בספרה אפס של ערך במערך של
אובייקטים מסוג
ContentProviderResult
מ-applyBatch()
. כשמפעילים את פעולות האצווה, התוצאה של כל פעולה מאוחסנת במערך ביניים של תוצאות. הערך שלpreviousResult
הוא האינדקס של אחת מהתוצאות האלה, שמאוחזר ונשמר עם הערך שלkey
. פעולה זו מאפשרת לך להוסיף רשומה גולמית חדשה של איש קשר ולחזור_ID
, ולאחר מכן ליצור הפניה חזרה ל כשמוסיפים שורהContactsContract.Data
.מערך התוצאות כולו נוצר בקריאה הראשונה ל-
applyBatch()
, בגודל שווה לגודל שלArrayList
של אובייקטיContentProviderOperation
שסיפקתם. אבל, כל הרכיבים במערך התוצאות מוגדרים ל-null
, ואם תנסו כדי לבצע הפניה חזרה לתוצאה של פעולה שעדיין לא הוחלה,withValueBackReference()
זורקתException
.
קטעי הקוד הבאים מראים איך להוסיף באצווה נתונים ואיש קשר גולמיים חדשים. הם כוללים קוד שמגדיר נקודת כניעה ומשתמש בהפניה לאחור.
קטע הקוד הראשון מאחזר את פרטי הקשר מממשק המשתמש. בשלב הזה, המשתמש כבר נבחר החשבון שעבורו יש להוסיף את איש הקשר הגולמי החדש.
Kotlin
// Creates a contact entry from the current UI values, using the currently-selected account. private fun createContactEntry() { /* * Gets values from the UI */ val name = contactNameEditText.text.toString() val phone = contactPhoneEditText.text.toString() val email = contactEmailEditText.text.toString() val phoneType: String = contactPhoneTypes[mContactPhoneTypeSpinner.selectedItemPosition] val emailType: String = contactEmailTypes[mContactEmailTypeSpinner.selectedItemPosition]
Java
// Creates a contact entry from the current UI values, using the currently-selected account. protected void createContactEntry() { /* * Gets values from the UI */ String name = contactNameEditText.getText().toString(); String phone = contactPhoneEditText.getText().toString(); String email = contactEmailEditText.getText().toString(); int phoneType = contactPhoneTypes.get( contactPhoneTypeSpinner.getSelectedItemPosition()); int emailType = contactEmailTypes.get( contactEmailTypeSpinner.getSelectedItemPosition());
קטע הקוד הבא יוצר פעולה להוספת שורת איש הקשר הגולמי לטבלה ContactsContract.RawContacts
:
Kotlin
/* * Prepares the batch operation for inserting a new raw contact and its data. Even if * the Contacts Provider does not have any data for this person, you can't add a Contact, * only a raw contact. The Contacts Provider will then add a Contact automatically. */ // Creates a new array of ContentProviderOperation objects. val ops = arrayListOf<ContentProviderOperation>() /* * Creates a new raw contact with its account type (server type) and account name * (user's account). Remember that the display name is not stored in this row, but in a * StructuredName data row. No other data is required. */ var op: ContentProviderOperation.Builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.name) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.type) // Builds the operation and adds it to the array of operations ops.add(op.build())
Java
/* * Prepares the batch operation for inserting a new raw contact and its data. Even if * the Contacts Provider does not have any data for this person, you can't add a Contact, * only a raw contact. The Contacts Provider will then add a Contact automatically. */ // Creates a new array of ContentProviderOperation objects. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); /* * Creates a new raw contact with its account type (server type) and account name * (user's account). Remember that the display name is not stored in this row, but in a * StructuredName data row. No other data is required. */ ContentProviderOperation.Builder op = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.getType()) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.getName()); // Builds the operation and adds it to the array of operations ops.add(op.build());
בשלב הבא, הקוד יוצר שורות נתונים לשורות של השם המוצג, הטלפון וכתובת האימייל.
כל אובייקט של בונה הפעולות משתמש
withValueBackReference()
כדי לקבל
RAW_CONTACT_ID
. נקודות ההתייחסות
חזרה לאובייקט ContentProviderResult
מהפעולה הראשונה,
שמוסיפה את השורה הגולמית של איש הקשר ומחזירה את הערך החדש _ID
עם ערך מסוים. כתוצאה מכך, כל שורת נתונים מקושרת באופן אוטומטי לפי הערך שלה בשדה RAW_CONTACT_ID
לשורת ContactsContract.RawContacts
החדשה שאליה היא שייכת.
האובייקט ContentProviderOperation.Builder
שמוסיף את שורת האימייל הוא
מסומנת באמצעות withYieldAllowed()
, שמגדירה נקודת תפוקה:
Kotlin
// Creates the display name for the new raw contact, as a StructuredName data row. op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * withValueBackReference sets the value of the first argument to the value of * the ContentProviderResult indexed by the second argument. In this particular * call, the raw contact ID column of the StructuredName data row is set to the * value of the result returned by the first operation, which is the one that * actually adds the raw contact row. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to StructuredName .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) // Sets the data row's display name to the name in the UI. .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name) // Builds the operation and adds it to the array of operations ops.add(op.build()) // Inserts the specified phone number and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Phone .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) // Sets the phone number and type .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone) .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType) // Builds the operation and adds it to the array of operations ops.add(op.build()) // Inserts the specified email and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Email .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) // Sets the email address and type .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email) .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType) /* * Demonstrates a yield point. At the end of this insert, the batch operation's thread * will yield priority to other threads. Use after every set of operations that affect a * single contact, to avoid degrading performance. */ op.withYieldAllowed(true) // Builds the operation and adds it to the array of operations ops.add(op.build())
Java
// Creates the display name for the new raw contact, as a StructuredName data row. op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * withValueBackReference sets the value of the first argument to the value of * the ContentProviderResult indexed by the second argument. In this particular * call, the raw contact ID column of the StructuredName data row is set to the * value of the result returned by the first operation, which is the one that * actually adds the raw contact row. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to StructuredName .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) // Sets the data row's display name to the name in the UI. .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name); // Builds the operation and adds it to the array of operations ops.add(op.build()); // Inserts the specified phone number and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Phone .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) // Sets the phone number and type .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone) .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType); // Builds the operation and adds it to the array of operations ops.add(op.build()); // Inserts the specified email and type as a Phone data row op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) /* * Sets the value of the raw contact id column to the new raw contact ID returned * by the first operation in the batch. */ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) // Sets the data row's MIME type to Email .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) // Sets the email address and type .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email) .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType); /* * Demonstrates a yield point. At the end of this insert, the batch operation's thread * will yield priority to other threads. Use after every set of operations that affect a * single contact, to avoid degrading performance. */ op.withYieldAllowed(true); // Builds the operation and adds it to the array of operations ops.add(op.build());
בקטע הקוד האחרון מוצגת הקריאה ל-applyBatch()
שמוסיפה את שורות הנתונים ואנשי הקשר הגולמיים החדשים.
Kotlin
// Ask the Contacts Provider to create a new contact Log.d(TAG, "Selected account: ${mSelectedAccount.name} (${mSelectedAccount.type})") Log.d(TAG, "Creating contact: $name") /* * Applies the array of ContentProviderOperation objects in batch. The results are * discarded. */ try { contentResolver.applyBatch(ContactsContract.AUTHORITY, ops) } catch (e: Exception) { // Display a warning val txt: String = getString(R.string.contactCreationFailure) Toast.makeText(applicationContext, txt, Toast.LENGTH_SHORT).show() // Log exception Log.e(TAG, "Exception encountered while inserting contact: $e") } }
Java
// Ask the Contacts Provider to create a new contact Log.d(TAG,"Selected account: " + selectedAccount.getName() + " (" + selectedAccount.getType() + ")"); Log.d(TAG,"Creating contact: " + name); /* * Applies the array of ContentProviderOperation objects in batch. The results are * discarded. */ try { getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); } catch (Exception e) { // Display a warning Context ctx = getApplicationContext(); CharSequence txt = getString(R.string.contactCreationFailure); int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(ctx, txt, duration); toast.show(); // Log exception Log.e(TAG, "Exception encountered while inserting contact: " + e); } }
פעולות באצווה מאפשרות גם להטמיע בקרה אופטימיסטית על בו-זמניות, שיטה להחיל עסקאות שינוי בלי לנעול את המאגר הבסיסי. כדי להשתמש בשיטה הזו, מחילים את העסקה ואז בודקים אם בוצעו בו-זמנית שינויים אחרים. אם תגלה שינוי לא עקבי, לבטל את העסקה ולנסות שוב.
בקרת בו-זמניות אופטימית שימושית למכשירים ניידים, שבהם יש רק משתמש אחד מספר מסוים של פעמים, והגישה למאגר הנתונים בו-זמנית היא נדירות. כי לא נעשה שימוש בנעילה, לא מתבזבז זמן על הגדרת נעילות או בהמתנה עד שעסקאות אחרות ישוחררו.
כדי להשתמש בבקרת בו-זמניות אופטימית בזמן עדכון
בשורה ContactsContract.RawContacts
, יש לבצע את השלבים הבאים:
-
אחזור
VERSION
של איש הקשר הגולמי יחד עם הנתונים האחרים שאתם מאחזרים. -
יצירת אובייקט
ContentProviderOperation.Builder
שמתאים ל: לאכוף אילוץ באמצעות השיטה,newAssertQuery(Uri)
. עבור ה-URI של התוכן, להשתמש ב-RawContacts.CONTENT_URI
שמוצמד אליו ה-_ID
של איש הקשר הגולמי. -
בשביל האובייקט
ContentProviderOperation.Builder
, קוראיםwithValue()
כדי להשוות אלVERSION
למספר הגרסה שאחזרת עכשיו. -
לאותו
ContentProviderOperation.Builder
, צריך להפעיל אתwithExpectedCount()
כדי לוודא שרק שורה אחת נבדקת על ידי ההצהרה הזו. -
קוראים אל
build()
כדי ליצור את האובייקטContentProviderOperation
, ואז להוסיף אותו בתור האובייקט הראשון בArrayList
שאליו מעביריםapplyBatch()
- מחילים את העסקה באצווה.
אם השורה הגולמית של איש הקשר מתעדכנת על ידי פעולה אחרת בין מועד קריאת השורה
הזמן שבו תנסה לשנות אותו, "הטענה" ContentProviderOperation
תיכשל, וכל הפעולות של כל הפעולות יגובו. לאחר מכן תוכלו לנסות שוב את האצווה או לבצע פעולה אחרת.
קטע הקוד הבא מדגים איך יוצרים 'הצהרה על זכויות יוצרים'
ContentProviderOperation
אחרי שאילתה על איש קשר גולמי אחד באמצעות
CursorLoader
:
Kotlin
/* * The application uses CursorLoader to query the raw contacts table. The system calls this method * when the load is finished. */ override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) { // Gets the raw contact's _ID and VERSION values rawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)) mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION)) } ... // Sets up a Uri for the assert operation val rawContactUri: Uri = ContentUris.withAppendedId( ContactsContract.RawContacts.CONTENT_URI, rawContactID ) // Creates a builder for the assert operation val assertOp: ContentProviderOperation.Builder = ContentProviderOperation.newAssertQuery(rawContactUri).apply { // Adds the assertions to the assert operation: checks the version withValue(SyncColumns.VERSION, mVersion) // and count of rows tested withExpectedCount(1) } // Creates an ArrayList to hold the ContentProviderOperation objects val ops = arrayListOf<ContentProviderOperation>() ops.add(assertOp.build()) // You would add the rest of your batch operations to "ops" here ... // Applies the batch. If the assert fails, an Exception is thrown try { val results: Array<ContentProviderResult> = contentResolver.applyBatch(AUTHORITY, ops) } catch (e: OperationApplicationException) { // Actions you want to take if the assert operation fails go here }
Java
/* * The application uses CursorLoader to query the raw contacts table. The system calls this method * when the load is finished. */ public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // Gets the raw contact's _ID and VERSION values rawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)); mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION)); } ... // Sets up a Uri for the assert operation Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactID); // Creates a builder for the assert operation ContentProviderOperation.Builder assertOp = ContentProviderOperation.newAssertQuery(rawContactUri); // Adds the assertions to the assert operation: checks the version and count of rows tested assertOp.withValue(SyncColumns.VERSION, mVersion); assertOp.withExpectedCount(1); // Creates an ArrayList to hold the ContentProviderOperation objects ArrayList ops = new ArrayList<ContentProviderOperation>; ops.add(assertOp.build()); // You would add the rest of your batch operations to "ops" here ... // Applies the batch. If the assert fails, an Exception is thrown try { ContentProviderResult[] results = getContentResolver().applyBatch(AUTHORITY, ops); } catch (OperationApplicationException e) { // Actions you want to take if the assert operation fails go here }
אחזור ושינוי באמצעות כוונות
שליחת כוונה לאפליקציית אנשי הקשר של המכשיר מאפשרת לכם לגשת לספק אנשי הקשר באופן עקיף. הכוונה מפעילה את ממשק המשתמש של אפליקציית אנשי הקשר במכשיר, שבו המשתמשים יכולים לבצע פעולות שקשורות לאנשי הקשר. עם סוג הגישה הזה, המשתמשים יכולים:
- בוחרים איש קשר מהרשימה ומחזירים אותו לאפליקציה להמשך העבודה.
- לערוך את הפרטים של איש קשר קיים.
- להוסיף איש קשר חדש ללא עיבוד לכל אחד מהחשבונות שלהם.
- מחיקה של איש קשר או של נתוני אנשי קשר.
אם המשתמש מוסיף או מעדכן נתונים, אפשר לאסוף את הנתונים קודם ולשלוח אותם בפורמט מכוונה.
כשמשתמשים בכוונות כדי לגשת לספק אנשי הקשר דרך אפליקציית אנשי הקשר של המכשיר, לא צריכים לכתוב ממשק משתמש או קוד משלכם כדי לגשת לספק. בנוסף, לא צריך לבקש הרשאה לקריאה או לכתיבה לספק. אפליקציית אנשי הקשר של המכשיר יכולה להעניק לכם הרשאת קריאה של איש קשר מסוים, ובגלל שאתם מבצעים שינויים באמצעות אפליקציה אחרת, אין צורך בהרשאות כתיבה.
התהליך הכללי של שליחת כוונה לגשת לספק מתואר בפירוט
המדריך הבסיסי לספקי תוכן בקטע 'גישה לנתונים באמצעות כוונות'. הפעולה, סוג ה-MIME וערכים של נתונים שבהם משתמשים במשימות הזמינות מפורטים בטבלה 4, ואילו הערכים הנוספים שבהם אפשר להשתמש עם putExtra()
מפורטים במסמכי העזרה של ContactsContract.Intents.Insert
:
טבלה 4. כוונות של ספק אנשי קשר.
משימה | פעולה | נתונים | סוג MIME | הערות |
---|---|---|---|---|
בחירת איש קשר מתוך רשימה | ACTION_PICK |
אחת מהאפשרויות:
|
צולם בלי מבזק |
מציגה רשימה של אנשי קשר גולמיים או רשימת נתונים מאיש קשר גולמי, בהתאם
סוג ה-URI של התוכן שסיפקתם.
שיחת טלפון
|
הוספת איש קשר גולמי חדש | Insert.ACTION |
לא רלוונטי |
RawContacts.CONTENT_TYPE , סוג MIME לקבוצת אנשי קשר גולמיים.
|
המסך הוספת איש קשר באפליקציית אנשי הקשר של המכשיר מוצג.
ערכי התוספות שהוספת ל-Intent מוצגים. אם שולחים את הבקשה עם startActivityForResult() , ה-URI של התוכן של איש הקשר הגולמי שנוסף מחדש מועבר בחזרה לשיטת ה-callback onActivityResult() של הפעילות, בארגומנט Intent , בשדה data. כדי לקבל את הערך, קוראים לפונקציה getData() .
|
עריכת איש קשר | ACTION_EDIT |
CONTENT_LOOKUP_URI עבור
איש הקשר. פעילות העורך תאפשר למשתמש לערוך את כל הנתונים המשויכים
עם איש הקשר הזה.
|
Contacts.CONTENT_ITEM_TYPE , איש קשר יחיד. |
מציג את המסך 'עריכת איש קשר' באפליקציית אנשי הקשר. מוצגים הערכים הנוספים שמוסיפים לכוונה. כשהמשתמש לוחץ על סיום כדי לשמור את העריכות, הפעילות חוזרת לחזית. |
הצגת בורר שאפשר להשתמש בו גם להוספת נתונים. | ACTION_INSERT_OR_EDIT |
לא רלוונטי |
CONTENT_ITEM_TYPE
|
כוונת החיפוש הזו תמיד מציגה את מסך הבחירה של אפליקציית אנשי הקשר. המשתמש יכול
בוחרים איש קשר לעריכה, או מוסיפים איש קשר חדש. עריכה או הוספה של מסך
מוצגות, בהתאם לבחירה של המשתמש, ולנתוני התוספות שאתם מעבירים
מוצגת. אם באפליקציה מוצגים פרטים ליצירת קשר כמו כתובת אימייל או מספר טלפון, אפשר להשתמש בכוונה הזו כדי לאפשר למשתמש להוסיף את הפרטים לאיש קשר קיים.
איש קשר,
הערה: אין צורך לשלוח ערך שם בתוספות של Intent זה. כי המשתמש תמיד בוחר שם קיים או מוסיף שם חדש. יתרה על כך, אם תשלחו שם והמשתמש יבחר לערוך, אפליקציית 'אנשי קשר' הצגת השם ששלחתם ותחליף את הערך הקודם. אם המשתמש לא שם לב לכך ושומר את העריכה, הערך הישן יימחק. |
אפליקציית 'אנשי קשר' במכשיר לא מאפשרת למחוק איש קשר גולמי או את הנתונים שלו עם
בכוונה טובה. במקום זאת, כדי למחוק איש קשר בפורמט גולמי, משתמשים ב-ContentResolver.delete()
או ב-ContentProviderOperation.newDelete()
.
קטע הקוד הבא מראה איך ליצור ולשלוח אובייקט Intent שמוסיף נתוני גולמיים חדשים. איש קשר ונתונים:
Kotlin
// Gets values from the UI val name = contactNameEditText.text.toString() val phone = contactPhoneEditText.text.toString() val email = contactEmailEditText.text.toString() val company = companyName.text.toString() val jobtitle = jobTitle.text.toString() /* * Demonstrates adding data rows as an array list associated with the DATA key */ // Defines an array list to contain the ContentValues objects for each row val contactData = arrayListOf<ContentValues>() /* * Defines the raw contact row */ // Sets up the row as a ContentValues object val rawContactRow = ContentValues().apply { // Adds the account type and name to the row put(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.type) put(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.name) } // Adds the row to the array contactData.add(rawContactRow) /* * Sets up the phone number data row */ // Sets up the row as a ContentValues object val phoneRow = ContentValues().apply { // Specifies the MIME type for this data row (all data rows must be marked by their type) put(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) // Adds the phone number and its type to the row put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone) } // Adds the row to the array contactData.add(phoneRow) /* * Sets up the email data row */ // Sets up the row as a ContentValues object val emailRow = ContentValues().apply { // Specifies the MIME type for this data row (all data rows must be marked by their type) put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) // Adds the email address and its type to the row put(ContactsContract.CommonDataKinds.Email.ADDRESS, email) } // Adds the row to the array contactData.add(emailRow) // Creates a new intent for sending to the device's contacts application val insertIntent = Intent(ContactsContract.Intents.Insert.ACTION).apply { // Sets the MIME type to the one expected by the insertion activity type = ContactsContract.RawContacts.CONTENT_TYPE // Sets the new contact name putExtra(ContactsContract.Intents.Insert.NAME, name) // Sets the new company and job title putExtra(ContactsContract.Intents.Insert.COMPANY, company) putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle) /* * Adds the array to the intent's extras. It must be a parcelable object in order to * travel between processes. The device's contacts app expects its key to be * Intents.Insert.DATA */ putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData) } // Send out the intent to start the device's contacts app in its add contact activity. startActivity(insertIntent)
Java
// Gets values from the UI String name = contactNameEditText.getText().toString(); String phone = contactPhoneEditText.getText().toString(); String email = contactEmailEditText.getText().toString(); String company = companyName.getText().toString(); String jobtitle = jobTitle.getText().toString(); // Creates a new intent for sending to the device's contacts application Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION); // Sets the MIME type to the one expected by the insertion activity insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE); // Sets the new contact name insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name); // Sets the new company and job title insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company); insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle); /* * Demonstrates adding data rows as an array list associated with the DATA key */ // Defines an array list to contain the ContentValues objects for each row ArrayList<ContentValues> contactData = new ArrayList<ContentValues>(); /* * Defines the raw contact row */ // Sets up the row as a ContentValues object ContentValues rawContactRow = new ContentValues(); // Adds the account type and name to the row rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.getType()); rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.getName()); // Adds the row to the array contactData.add(rawContactRow); /* * Sets up the phone number data row */ // Sets up the row as a ContentValues object ContentValues phoneRow = new ContentValues(); // Specifies the MIME type for this data row (all data rows must be marked by their type) phoneRow.put( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE ); // Adds the phone number and its type to the row phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone); // Adds the row to the array contactData.add(phoneRow); /* * Sets up the email data row */ // Sets up the row as a ContentValues object ContentValues emailRow = new ContentValues(); // Specifies the MIME type for this data row (all data rows must be marked by their type) emailRow.put( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE ); // Adds the email address and its type to the row emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email); // Adds the row to the array contactData.add(emailRow); /* * Adds the array to the intent's extras. It must be a parcelable object in order to * travel between processes. The device's contacts app expects its key to be * Intents.Insert.DATA */ insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData); // Send out the intent to start the device's contacts app in its add contact activity. startActivity(insertIntent);
תקינות נתונים
מאגר אנשי הקשר מכיל מידע חשוב ורגיש שהמשתמשים מצפים שיהיה נכון ועדכני, ולכן ל-Contacts Provider יש כללים מוגדרים היטב לשמירה על תקינות הנתונים. באחריותכם לפעול בהתאם לכללים האלה כשאתם משנים את נתוני אנשי הקשר. הדבר החשוב הכללים מפורטים כאן:
-
תמיד צריך להוסיף שורה של
ContactsContract.CommonDataKinds.StructuredName
עבור כל שורהContactsContract.RawContacts
שמוסיפים. -
שורה
ContactsContract.RawContacts
בלי שורהContactsContract.CommonDataKinds.StructuredName
הטבלהContactsContract.Data
עלולה לגרום לבעיות במהלך או צבירת נתונים. -
תמיד צריך לקשר שורות
ContactsContract.Data
חדשות לשורת ההורה שלהן,ContactsContract.RawContacts
. -
שורה של
ContactsContract.Data
שלא מקושרת אל המכשירContactsContract.RawContacts
לא יהיה גלוי של אנשי קשר, והיא עלולה לגרום לבעיות עם מתאמי סנכרון. - לשנות את הנתונים רק של אנשי הקשר הגולמיים שבבעלותכם.
- חשוב לזכור שספק אנשי הקשר בדרך כלל מנהל נתונים מכמה סוגים שונים של חשבונות או שירותים אונליין. צריך לוודא שהאפליקציה שלך משנה רק את השינויים או מוחקת נתונים של שורות ששייכות לך, ומוסיפה נתונים רק עם סוג החשבון והשם שלו שנמצאים בשליטתך.
-
צריך להשתמש תמיד בקבועים שהוגדרו ב-
ContactsContract
וב מחלקות משנה של רשויות, מזהי URI של תוכן, נתיבי URI, שמות עמודות, סוגי MIMETYPE
ערכים. - שימוש בקבועים האלה עוזר להימנע משגיאות. תקבלו גם התראות מהמחשב אם אחת מהקבועות הוצאה משימוש.
שורות של נתונים בהתאמה אישית
כדי ליצור סוגי MIME מותאמים אישית ולהשתמש בהם, אפשר להוסיף, לערוך, למחוק ולאחזר
שורות נתונים משלך בטבלה ContactsContract.Data
. השורות שלך
מוגבלים לשימוש בעמודה שהוגדרה
ContactsContract.DataColumns
, אבל יש לך אפשרות למפות אתרים משלך
שמות של עמודות ספציפיות לשמות העמודות שמוגדרים כברירת מחדל. באפליקציית אנשי הקשר של המכשיר,
נתוני השורות מוצגים אבל לא ניתן לערוך או למחוק אותם, והמשתמשים לא יכולים להוסיף
נתונים נוספים. כדי לאפשר למשתמשים לשנות את שורות הנתונים בהתאמה אישית, צריך לספק עורך
פעילות באפליקציה שלכם.
כדי להציג את הנתונים המותאמים אישית, צריך לספק קובץ contacts.xml
שמכיל רכיב <ContactsAccountType>
ואחד או יותר מרכיבי הצאצא שלו <ContactsDataKind>
. הנושא הזה מוסבר בפירוט בקטע <ContactsDataKind> element
.
למידע נוסף על סוגי MIME מותאמים אישית, ניתן לקרוא את מדריך ליצירת ספק תוכן.
מתאמי סנכרון של ספק אנשי הקשר
ספק אנשי הקשר מיועד ספציפית לטיפול בסנכרון של נתונים של אנשי קשר בין מכשיר לשירות באינטרנט. כך המשתמשים יכולים להוריד נתונים קיימים למכשיר חדש ולהעלות נתונים קיימים לחשבון חדש. הסנכרון מבטיח גם שהמשתמשים יקבלו את הנתונים העדכניים ביותר, ללא קשר המקור של התוספות והשינויים. יתרון נוסף של הסנכרון הוא שנתוני אנשי הקשר זמינים גם כשהמכשיר לא מחובר לרשת.
אפשר להטמיע סנכרון במגוון דרכים, אבל מערכת Android מספקת מסגרת לסנכרון יישומי פלאגין שהופכת את המשימות הבאות לאוטומטיות:
- בדיקת זמינות הרשת.
- תזמון וביצוע סנכרון על סמך העדפות המשתמשים.
- הפעלה מחדש של סנכרון שנעצר.
כדי להשתמש במסגרת הזו, אתם צריכים לספק פלאגין של מתאם סנכרון. כל מתאם סנכרון הוא ייחודי ספק שירות ותוכן, אבל יכול לטפל בכמה שמות של חשבונות עבור אותו שירות. framework מאפשרת גם כמה מתאמי סנכרון לאותו שירות ולאותו ספק.
סנכרון של סוגי מתאמים וקבצים
אתם מטמיעים מתאם סנכרון כמחלקה משנה של
AbstractThreadedSyncAdapter
ולהתקין אותו כחלק מ-Android
תרגום מכונה. המערכת לומדת על מתאם הסנכרון מאלמנטים באפליקציה
ומקובץ XML מיוחד שהמניפסט מפנה אליו. קובץ ה-XML מגדיר את
סוג החשבון לשירות אונליין ולרשות של ספק התוכן, שיחד
המזהה הייחודי של המתאם. מתאם הסנכרון לא פעיל עד שהמשתמש מוסיף חשבון לסוג החשבון של מתאם הסנכרון ומפעיל את הסנכרון עם ספק התוכן שאליו מתבצע הסנכרון. בשלב הזה המערכת מתחילה לנהל את המתאם, ומפעילה אותו לפי הצורך כדי לסנכרן בין ספק התוכן לבין השרת.
הערה: שימוש בסוג חשבון כחלק מהזיהוי של מתאם הסנכרון מאפשר למערכת לזהות ולקבץ יחד מתאמי סנכרון שיש להם גישה לשירותים שונים מאותו ארגון. לדוגמה, לכל מתאמי הסנכרון של שירותי Google אונליין יש את אותו סוג חשבון com.google
. כשמשתמשים מוסיפים חשבון Google למכשירים שלהם, כל מתאמי הסנכרון המותקנים לשירותי Google מופיעים יחד ברשימה. כל מתאם סנכרון שמופיע ברשימה מסתנכרן עם ספק תוכן אחר במכשיר.
מאחר שרוב השירותים דורשים מהמשתמשים לאמת את הזהות שלהם לפני שהם יכולים לגשת לנתונים, מערכת Android מציעה מסגרת אימות שדומה למסגרת של מתאם הסנכרון, ולעיתים קרובות משתמשים בה בשילוב עם המסגרת הזו. מסגרת האימות משתמשת באימותי פלאגין שהם קבוצות משנה של AbstractAccountAuthenticator
. מאמת חשבונות מאמת
את זהות המשתמש לפי השלבים הבאים:
- אוסף את שם המשתמש, סיסמה או מידע דומה ( פרטי כניסה).
- שליחת פרטי הכניסה לשירות
- בדיקת התשובה של השירות.
אם השירות מקבל את פרטי הכניסה, מאמת החשבונות יכול לשמור אותם לשימוש מאוחר יותר. בגלל מסגרת האימות של הפלאגין, ה-AccountManager
יכול לספק גישה לכל אסימון אימות שתומך בו האימות ובוחר לחשוף, כמו אסימוני אימות של OAuth2.
למרות שלא נדרש אימות, רוב שירותי אנשי הקשר משתמשים בו. עם זאת, אין צורך להשתמש במסגרת האימות של Android כדי לבצע אימות.
הטמעת מתאם סנכרון
כדי להטמיע מתאם סנכרון עבור ספק אנשי הקשר, צריך להתחיל ביצירת אפליקציית Android שמכילה את הפרטים הבאים:
-
רכיב
Service
שמגיב לבקשות מהמערכת כדי חיבור למתאם הסנכרון. -
כשהמערכת רוצה להריץ סנכרון, היא קוראת ל-method
onBind()
של השירות כדי לקבלIBinder
למתאם הסנכרון. כך המערכת יכולה מבצעים קריאות שונות ב-methods של המתאם. -
מתאם הסנכרון בפועל, שמיושם כסוג משנה קונקרטי של
AbstractThreadedSyncAdapter
. -
הכיתה הזו מורידה נתונים מהשרת, ומעלה נתונים
המכשיר ופתרון התנגשויות. העבודה העיקרית של המתאם היא
מבצעים את הפעולה הזאת בשיטה
onPerformSync()
. המחלקה הזו חייבת להיות מופצת כ-Singleton. -
מחלקה של
Application
. -
הסיווג הזה משמש כמפעל עבור singleton של מתאם הסנכרון. משתמשים בשיטה
onCreate()
כדי ליצור מופע של מתאם הסנכרון, ומספקים שיטה סטטית מסוג 'getter' כדי להחזיר את ה-Singleton לשיטהonBind()
של השירות של מתאם הסנכרון. -
אופציונלי: רכיב
Service
שמגיב בקשות מהמערכת לאימות משתמשים. -
AccountManager
מפעיל את השירות הזה כדי להתחיל את האימות תהליך האימות. ה-methodonCreate()
של השירות יוצרת של מאמת החשבונות. כשהמערכת רוצה לאמת חשבון משתמש למתאמת הסנכרון של האפליקציה, היא קוראת לשיטהonBind()
של השירות כדי לקבלIBinder
לאימות. כך המערכת יכולה לבצע קריאות צולבות ל-methods של המאמת. -
אופציונלי: תת-סוג קונקרטי של
AbstractAccountAuthenticator
שמטפל בבקשות לאימות. -
בכיתה הזו מפורטות שיטות שמופעלות על ידי
AccountManager
כדי לאמת את פרטי הכניסה של המשתמש מול השרת. הפרטים של תהליכי האימות משתנים במידה רבה, בהתאם לטכנולוגיית השרת שבה משתמשים. אתם צריכים לקבלת מידע נוסף על אימות, אפשר לעיין בתיעוד של תוכנת השרת שלכם. - קובצי XML שמגדירים את מתאם הסנכרון ואת המאמת למערכת.
-
רכיבי השירות של מתאם הסנכרון ומאמת הזהות שתוארו למעלה מוגדרים ברכיבי
<service>
במניפסט של האפליקציה. הרכיבים האלה מכילים<meta-data>
ורכיבי צאצא שמספקים נתונים ספציפיים למערכת:-
<meta-data>
עבור נקודות השירות של מתאם הסנכרון קובץ XMLres/xml/syncadapter.xml
. קובץ זה מציין URI של שירות האינטרנט שיתוזמן עם ספק אנשי הקשר, וגם סוג חשבון לשירות האינטרנט. -
אופציונלי: הרכיב
<meta-data>
של המאמת מפנה לקובץ ה-XMLres/xml/authenticator.xml
. בתורו, הקובץ הזה מציין את סוג החשבון שנתמך בכלי האימות הזה, וגם משאבי ממשק משתמש מופיעות בתהליך האימות. סוג החשבון שצוין הרכיב חייב להיות זהה לסוג החשבון שצוין לסנכרון עם מתאם בלבד.
-
נתונים של מקור נתונים ברשתות חברתיות
android.provider.ContactsContract.StreamItems וגם טבלאות של android.provider.ContactsContract.StreamItemPhotos לנהל נתונים נכנסים מרשתות חברתיות. אפשר לכתוב מתאם סנכרון שמוסיף נתוני סטרימינג מהרשת שלכם לטבלאות האלה, או לקרוא נתוני מקורות מהטבלאות האלה להציג אותו באפליקציה שלכם, או בשניהם. בעזרת התכונות האלה, תוכלו לשלב את האפליקציות והשירותים של הרשתות החברתיות בחוויית השימוש של Android ברשתות החברתיות.
טקסט של שידור ברשתות חברתיות
פריטים בסטרימינג תמיד משויכים לאיש קשר גולמי.
android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID מקשר אל
הערך של _ID
עבור איש הקשר הגולמי. סוג החשבון ושם החשבון של נתוני הגולמיים
אנשי קשר שמורים גם בשורת הפריט של עדכוני התוכן.
שומרים את הנתונים מהמקור בעמודות הבאות:
- android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE
- חובה. סוג החשבון של המשתמש בפרטי איש הקשר הגולמיים שמשויכים לפריט הזה בסטרימינג. אל תשכחו להגדיר את הערך הזה כשמוסיפים פריט לשידור.
- android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME
- חובה. שם החשבון של המשתמש לאיש הקשר הגולמי שמשויך לפריט הסטרימינג הזה. אל תשכחו להגדיר את הערך הזה כשמוסיפים פריט לשידור.
- עמודות מזהה
-
חובה. כשאתם מוסיפים פריט בסטרימינג, עליכם להוסיף את העמודות הבאות של המזהים:
- android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID: הערך android.provider.BaseColumns#_ID של איש הקשר שהמקור הזה הוא משויך אל.
- android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY: הערך של android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY של איש הקשר שאליו משויך פריט הסטרימינג הזה.
- android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID: הערך של android.provider.BaseColumns#_ID של איש הקשר הגולמי שאליו משויך פריט המקור הזה.
- android.provider.ContactsContract.StreamItemsColumns#COMMENTS
- אופציונלי. מאחסן מידע סיכום שאפשר להציג בתחילת פריט בסטרימינג.
- android.provider.ContactsContract.StreamItemsColumns#TEXT
-
הטקסט של הפריט שבעדכוני התוכן, כלומר התוכן שפורסם על ידי מקור הפריט,
או תיאור של פעולה כלשהי שיצרה את הפריט בזרם. העמודה הזו יכולה להכיל כל עיצוב ותמונות מוטמעות של משאבים שאפשר להציג באמצעות
fromHtml()
. יכול להיות שהספק יקצר תוכן ארוך או ידגיש אותו בקו אליפטי, אבל הוא ינסה להימנע משבירת תגים. - android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP
- מחרוזת טקסט שמכילה את הזמן שבו הפריט נוסף או עודכן בטופס, של אלפיות שנייה מתחילת התקופה. אפליקציות שמכניסות או מעדכנות פריטים בזרם האחראית לתחזוקת העמודה הזו, הוא לא מנוהל באופן אוטומטי על ידי ספק אנשי הקשר.
כדי להציג פרטים מזהים של הפריטים בפיד, צריך להשתמש ב android.provider.ContactsContract.StreamItemsColumns#RES_ICON, android.provider.ContactsContract.StreamItemsColumns#RES_LABEL וכן android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE כדי לקשר למשאבים באפליקציה שלכם.
הטבלה android.provider.ContactsContract.StreamItems מכילה גם את העמודות. android.provider.ContactsContract.StreamItemsColumns#SYNC1 עד android.provider.ContactsContract.StreamItemsColumns#SYNC4 לשימוש בלעדי ב- מתאמי סנכרון.
תמונות מזרם הפעילות ברשתות החברתיות
בטבלה android.provider.ContactsContract.StreamItemPhotos מאוחסנות תמונות שמשויכות לפריט במסך הבית. המיקום של הטבלה
העמודה android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID
קישורים לערכים בעמודה _ID
של
הטבלה android.provider.ContactsContract.StreamItems. ההפניות לתמונות מאוחסנות בטבלה בעמודות הבאות:
- העמודה android.provider.ContactsContract.StreamItemPhotos#PHOTO (BLOB).
- ייצוג בינארי של התמונה, שגודלו משתנה על ידי הספק לאחסון ולהצגה. העמודה הזו זמינה לצורך תאימות לאחור לגרסאות קודמות של 'אנשי קשר' הספק שהשתמש בו לאחסון תמונות. אבל בגרסה הנוכחית אין להשתמש בעמודה הזו לאחסון תמונות. במקום זאת, השתמשו android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID או android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI (שניהם שמתוארים בנקודות הבאות) כדי לאחסן תמונות בקובץ. העמודה הזו עכשיו מכיל תמונה ממוזערת של התמונה, שזמינה לקריאה.
- android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID
-
מזהה מספרי של תמונה של איש קשר בפורמט גולמי. מוסיפים את הערך הזה לקבוע
DisplayPhoto.CONTENT_URI
כדי לקבל URI של תוכן שמצביע על קובץ תמונה יחיד, ואז להתקשרopenAssetFileDescriptor()
כדי לקבל כינוי לקובץ התמונה. - android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI
-
URI של תוכן שמצביע ישירות אל קובץ התמונה של התמונה שמיוצגת על ידי השורה הזו.
צריך להתקשר אל
openAssetFileDescriptor()
עם ה-URI הזה כדי לקבל כינוי לקובץ התמונה.
שימוש בטבלאות של הרשתות החברתיות
הטבלאות האלה פועלות בדיוק כמו הטבלאות הראשיות האחרות בספק אנשי הקשר, למעט אלה:
- לטבלאות האלה נדרשות הרשאות גישה נוספות. כדי לקרוא מהם, האפליקציה חייבת להיות ההרשאה android.Manifest.permission#READ_SOCIAL_STREAM. שפת תרגום תשנה אותם, האפליקציה שלך צריכה לקבל הרשאה android.Manifest.permission#WRITE_SOCIAL_STREAM.
-
בטבלה android.provider.ContactsContract.StreamItems, מספר השורות
לכל איש קשר גולמי יש גישה מוגבלת. כשתגיעו למגבלה,
ספק אנשי הקשר מפנה מקום לשורות פריטים חדשות של עדכוני התוכן על ידי מחיקה אוטומטית
השורות עם הנתונים הישנים ביותר
android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP. כדי לקבל את המגבלה, שולחים שאילתה ל-URI של התוכן android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI. אפשר לעזוב את הפגישה
כל הארגומנטים מלבד ה-URI של התוכן שהוגדר ל-
null
. השאילתה מחזירה סמן שמכיל שורה אחת, עם העמודה היחידה android.provider.ContactsContract.StreamItems#MAX_ITEMS.
הכיתה android.provider.ContactsContract.StreamItems.StreamItemPhotos מגדירה טבלת משנה של android.provider.ContactsContract.StreamItemPhotos שמכילה את שורות התמונות של פריט אחד במקור החדשות.
אינטראקציות עם שידור חי ברשתות חברתיות
נתוני הזרם ברשתות החברתיות שמנוהלים על ידי הספק 'אנשי קשר', בשילוב עם אפליקציית אנשי הקשר במכשיר, מציעה דרך עוצמתית לחבר את מערכת הרשת החברתית שלכם עם אנשי קשר קיימים. התכונות הבאות זמינות:
- כשמסנכרנים את שירות הרשת החברתית עם ספק אנשי הקשר באמצעות מתאם סנכרון, אפשר לאחזר את הפעילות האחרונה של אנשי הקשר של המשתמש ולאחסן אותה בטבלאות android.provider.ContactsContract.StreamItems ו-android.provider.ContactsContract.StreamItemPhotos לשימוש עתידי.
- בנוסף לסנכרון הרגיל, אפשר להפעיל את מתאם הסנכרון כדי לאחזר נתונים נוספים כשהמשתמש בוחר איש קשר להצגה. כך מתאם הסנכרון יוכל לאחזר תמונות ברזולוציה גבוהה ואת הפריטים האחרונים שפורסמו בסטורי של איש הקשר.
- על ידי רישום התראה באפליקציית אנשי הקשר של המכשיר ובאפליקציית 'אנשי קשר' ספק, יש לך אפשרות לקבל כוונה לצפות באיש קשר מסוים ובאותו זמן לעדכן את הסטטוס של איש הקשר מהשירות. הגישה הזו עשויה להיות מהירה יותר ולצרוך פחות רוחב פס מאשר סנכרון מלא באמצעות מתאם סנכרון.
- המשתמשים יכולים להוסיף איש קשר לשירות הרשת החברתית שלכם כשהם צופים באיש הקשר באפליקציית אנשי הקשר של המכשיר. אפשר להפעיל את האפשרות הזו באמצעות 'הזמנת איש קשר' פיצ'ר, שאתה מפעיל באמצעות שילוב של פעילות שמוסיפה איש קשר קיים רשת, וקובץ XML שמספק את אפליקציית אנשי הקשר של המכשיר ספק אנשי הקשר עם פרטי האפליקציה שלכם.
סנכרון קבוע של פריטי הסטרימינג עם ספק אנשי הקשר זהה לסנכרון עם ספקים אחרים. מידע נוסף על סנכרון זמין בקטע מתאמי סנכרון של ספקי אנשי קשר. בקטעים הבאים מוסבר איך לרשום התראות ולהזמין אנשי קשר.
רישום לטיפול בבקשות לצפיות ברשתות חברתיות
כדי לרשום את מתאם הסנכרון לקבלת התראות כשמשתמש צופה באיש קשר מנוהל על ידי מתאם הסנכרון:
-
יצירת קובץ בשם
contacts.xml
ב-res/xml/
של הפרויקט אם הקובץ הזה כבר נמצא ברשותך, אפשר לדלג על השלב הזה. -
לקובץ הזה, מוסיפים את הרכיב
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
אם הרכיב הזה כבר קיים, אפשר לדלג על השלב הזה. -
כדי לרשום שירות שמקבל התראה כשהמשתמש פותח דף פרטים של איש קשר
את אפליקציית אנשי הקשר של המכשיר, צריך להוסיף את המאפיין
viewContactNotifyService="serviceclass"
לרכיב, כאשרserviceclass
הוא שם הסיווג המוגדר במלואו של השירות שאמור לקבל את הכוונה מאפליקציית אנשי הקשר של המכשיר. עבור שירות ההתראות השירות, משתמשים במחלקה שמרחיבה אתIntentService
כדי לאפשר לשירות לקבל כוונות. הנתונים בהפניה הנכנסת מכילים את ה-URI של התוכן של נתוני ה-Intent הגולמיים איש הקשר שעליו המשתמש לחץ. משירות שירות ההתראות, ניתן לבצע קישור אל ואז להתקשר אל לסנכרון הנתונים של איש הקשר הגולמי.
כדי לרשום פעילות שתתבצע קריאה כשמשתמש לוחץ על פריט בשידור, על תמונה או על שניהם:
-
יצירת קובץ בשם
contacts.xml
ב-res/xml/
של הפרויקט אם הקובץ כבר קיים, אפשר לדלג על השלב הזה. -
בקובץ הזה, מוסיפים את הרכיב
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
. אם הרכיב הזה כבר קיים, אפשר לדלג על השלב הזה. -
כדי לרשום אחת מהפעילויות שלכם לטפל במקרה שבו המשתמש לוחץ על פריט בסטרימינג באפליקציית אנשי הקשר של המכשיר, מוסיפים את המאפיין
viewStreamItemActivity="activityclass"
לאלמנט, כאשרactivityclass
הוא שם הכיתה המלא של הפעילות שאמורה לקבל את הכוונה מאפליקציית אנשי הקשר של המכשיר. -
כדי לרשום אחת מהפעילויות שלכם לטפל במקרה שבו המשתמש לוחץ על תמונה בסטרים באפליקציית אנשי הקשר של המכשיר, מוסיפים את המאפיין
viewStreamItemPhotoActivity="activityclass"
לאלמנט, כאשרactivityclass
הוא שם הכיתה המלא של הפעילות שאמורה לקבל את ה-Intent מאפליקציית אנשי הקשר של המכשיר.
תיאור מפורט יותר של הרכיב <ContactsAccountType>
זמין בקטע הרכיב <ContactsAccountType>.
ה-Intent הנכנס מכיל את ה-URI של התוכן של הפריט או התמונה שהמשתמש לחץ עליהם. כדי ליצור פעילויות נפרדות לפריטי טקסט ולתמונות, צריך להשתמש בשני המאפיינים באותו קובץ.
אינטראקציה עם שירות הרשת החברתית שלכם
המשתמשים לא צריכים לצאת מאפליקציית אנשי הקשר של המכשיר כדי להזמין איש קשר לרשת החברתית. לאחר יצירת רישות. במקום זאת, אפשר להגדיר שאפליקציית אנשי הקשר במכשיר תשלח כוונה להזמנת איש הקשר לאחת מהפעילויות שלכם. כדי להגדיר זאת:
-
יצירת קובץ בשם
contacts.xml
ב-res/xml/
של הפרויקט אם כבר יש לכם את הקובץ הזה, אתם יכולים לדלג על השלב הזה. -
לקובץ הזה, מוסיפים את הרכיב
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android">
אם הרכיב הזה כבר קיים, אפשר לדלג על השלב הזה. -
מוסיפים את המאפיינים הבאים:
inviteContactActivity="activityclass"
-
inviteContactActionLabel="@string/invite_action_label"
activityclass
הוא שם המחלקה המלא של הפעילות שאמורה לקבל את ה-Intent.invite_action_label
הוא מחרוזת טקסט שמוצגת בתפריט Add Connection (הוספת חיבור) יישום אנשי הקשר של המכשיר.
הערה: ContactsSource
הוא שם תג שהוצא משימוש עבור ContactsAccountType
.
מסמך עזר בנושא contacts.xml
הקובץ contacts.xml
מכיל רכיבי XML ששולטים באינטראקציה של
לסנכרן את המתאם והאפליקציה עם אפליקציית אנשי הקשר וספק אנשי הקשר. האלה
כמתואר בקטעים הבאים.
<ContactsAccountType> רכיב
האלמנט <ContactsAccountType>
קובע את האינטראקציה של האפליקציה שלכם עם אפליקציית אנשי הקשר. זהו התחביר הבא:
<ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android" inviteContactActivity="activity_name" inviteContactActionLabel="invite_command_text" viewContactNotifyService="view_notify_service" viewGroupActivity="group_view_activity" viewGroupActionLabel="group_action_text" viewStreamItemActivity="viewstream_activity_name" viewStreamItemPhotoActivity="viewphotostream_activity_name">
נכלל ב:
res/xml/contacts.xml
יכולים להכיל:
<ContactsDataKind>
תיאור:
מצהירה על רכיבי Android ותוויות של ממשק משתמש שמאפשרות למשתמשים להזמין אחד מאנשי הקשר שלהם אל רשת חברתית, להודיע למשתמשים כאשר אחד מהרשתות החברתיות שלהם מתעדכן, וכן וכן הלאה.
שימו לב שקידומת המאפיין android:
לא נדרשת למאפיינים של <ContactsAccountType>
.
מאפיינים:
inviteContactActivity
- שם הכיתה המלא של הפעילות באפליקציה שרוצים להפעיל כשהמשתמש בוחר באפשרות Add connection באפליקציית אנשי הקשר של המכשיר.
inviteContactActionLabel
-
מחרוזת טקסט שמוצגת לפעילות שצוינה ב-
inviteContactActivity
, בתפריט Add connection. לדוגמה, אפשר להשתמש במחרוזת 'לעקוב ברשת שלי'. אפשר להשתמש במשאב מחרוזות של התווית הזו. viewContactNotifyService
- שם הסיווג המוגדר במלואו של השירות באפליקציה שלכם, שאמור לקבל כאשר משתמש צופה באיש קשר. ההתראה הזו נשלחת על ידי אפליקציית אנשי הקשר במכשיר, והיא מאפשרת לאפליקציה לדחות פעולות שמתבצעות באמצעות כמות גדולה של נתונים עד שהן נדרשות. לדוגמה, האפליקציה יכולה להגיב להתראה הזו על ידי קריאה והצגה של התמונה באיכות גבוהה של איש הקשר ושל הפריטים האחרונים בסטטוס שלו ברשתות החברתיות. תיאור מפורט יותר של התכונה הזו זמין בקטע אינטראקציות בסטרים של רשתות חברתיות.
viewGroupActivity
- השם המלא של הכיתה של פעילות באפליקציה שיכולה להציג מידע על קבוצות. כשהמשתמש לוחץ על תווית הקבוצה באנשי הקשר במכשיר האפליקציה, ממשק המשתמש של פעילות זו מוצג.
viewGroupActionLabel
-
התווית שאפליקציית 'אנשי הקשר' מציגה לפקד של ממשק משתמש שמאפשר
למשתמש לצפות בקבוצות באפליקציה שלכם.
אפשר להשתמש במזהה משאב של מחרוזת במאפיין הזה.
viewStreamItemActivity
- שם הכיתה המלא של פעילות באפליקציה, שאפליקציית אנשי הקשר במכשיר מפעילה כשהמשתמש לוחץ על פריט בסטרימינג של איש קשר גולמי.
viewStreamItemPhotoActivity
- שם הכיתה המלא של פעילות באפליקציה שלכם, שאפליקציית אנשי הקשר במכשיר מפעילה כשהמשתמש לוחץ על תמונה בפריט בסטרימינג של איש קשר גולמי.
האלמנט <ContactsDataKind>
הרכיב <ContactsDataKind>
שולט בתצוגה של
שורות נתונים מותאמות אישית בממשק המשתמש של אפליקציית אנשי הקשר. התחביר שלו הוא:
<ContactsDataKind android:mimeType="MIMEtype" android:icon="icon_resources" android:summaryColumn="column_name" android:detailColumn="column_name">
מופיע ב:
<ContactsAccountType>
תיאור:
צריך להשתמש ברכיב הזה כדי שאפליקציית 'אנשי קשר' תציג את התוכן של שורת נתונים בהתאמה אישית בתור
חלק מהפרטים של איש קשר גולמי. כל רכיב צאצא אחד (<ContactsDataKind>
)
מסוג <ContactsAccountType>
מייצג סוג של שורת נתונים בהתאמה אישית שהסנכרון שלכם
המתאם מתווסף לטבלה ContactsContract.Data
. הוספה של
רכיב <ContactsDataKind>
לכל סוג MIME מותאם אישית שבו משתמשים. אין צורך להוסיף את הרכיב אם יש לכם שורת נתונים מותאמת אישית שאתם לא רוצים להציג בה נתונים.
מאפיינים:
android:mimeType
-
סוג MIME המותאם אישית שהגדרתם לאחד מסוגי שורות הנתונים המותאמים אישית
הטבלה
ContactsContract.Data
. לדוגמה, הערךvnd.android.cursor.item/vnd.example.locationstatus
יכול להיות מותאם אישית סוג MIME בשורת נתונים שמתעדת את המיקום הידוע האחרון של איש הקשר. android:icon
- מכשיר Android משאב שניתן לשרטוט שאפליקציית 'אנשי קשר' מציגה לצד הנתונים שלכם. אפשר להשתמש בו כדי להצביע למשתמש שהנתונים מגיעים מהשירות שלכם.
android:summaryColumn
- שם העמודה של הערך הראשון מתוך שני שאוחזר משורת הנתונים. מוצג בתור השורה הראשונה ברשומה עבור שורת הנתונים הזו. השורה הראשונה היא שמיועד לשמש כסיכום של הנתונים, אבל זה אופציונלי. אפשר לעיין גם במאמר android:detailColumn.
android:detailColumn
-
שם העמודה של הערך השני מתוך שני ערכים שאוחזרו משורת הנתונים. הערך הוא
מוצגת כשורה השנייה של הרשומה עבור שורת הנתונים הזו. עוד באותו הקשר
android:summaryColumn
תכונות נוספות של ספק אנשי הקשר
בנוסף לתכונות הראשיות המתוארות בקטעים הקודמים, ספק אנשי הקשר מציע את התכונות השימושיות הבאות לעבודה עם נתוני אנשי הקשר:
- קבוצות של אנשי קשר
- תכונות שקשורות לתמונות
קבוצות של אנשי קשר
ספק אנשי הקשר יכול באופן אופציונלי להוסיף תוויות לאוספים של אנשי קשר קשורים עם
לקבץ נתונים. אם השרת משויך לחשבון משתמש
אם רוצים לתחזק קבוצות, מתאם הסנכרון של סוג החשבון אמור להעביר
מקבץ נתונים בין ספק אנשי הקשר לשרת. כשמשתמשים מוסיפים איש קשר חדש לשרת ואז מוסיפים אותו לקבוצה חדשה, מתאם הסנכרון צריך להוסיף את הקבוצה החדשה לטבלה ContactsContract.Groups
. הקבוצה או מקבצת קובץ RAW
אנשי הקשר ששייכים ל- מאוחסנים בטבלה ContactsContract.Data
, באמצעות
סוג ה-MIME ContactsContract.CommonDataKinds.GroupMembership
.
אם אתם מתכננים מתאם סנכרון שיוסיף נתונים גולמיים של אנשי קשר מ-
לספק אנשי הקשר, ואתם לא משתמשים בקבוצות, עליכם לומר
ספק כדי שהנתונים שלך יהיו גלויים. בקוד שמופעל כשמשתמש מוסיף חשבון למכשיר, מעדכנים את השורה ContactsContract.Settings
שספק אנשי הקשר מוסיף לחשבון. בשורה הזו, מגדירים את הערך של העמודה Settings.UNGROUPED_VISIBLE
כ-1. ביצוע פעולה זו, ספק אנשי הקשר תמיד
להגדיר את הנתונים של אנשי הקשר כגלויים גם אם אתם לא משתמשים בקבוצות.
התמונות של אנשי הקשר
התמונות בטבלה ContactsContract.Data
נשמרות כשורות עם סוג MIME
Photo.CONTENT_ITEM_TYPE
. שם השורה
העמודה CONTACT_ID
מקושרת
עמודה _ID
של איש הקשר הגולמי שאליו היא שייכת.
המחלקה ContactsContract.Contacts.Photo
מגדירה טבלת משנה של
ContactsContract.Contacts
עם פרטי התמונה של איש הקשר
התמונה הראשית, שהיא התמונה הראשית של איש הקשר הגולמי של איש הקשר. באופן דומה,
המחלקה ContactsContract.RawContacts.DisplayPhoto
מגדירה טבלת משנה
מתוך ContactsContract.RawContacts
, שמכילים פרטי תמונה של
התמונה הראשית של איש הקשר.
מאמרי העזרה של ContactsContract.Contacts.Photo
וגם
ContactsContract.RawContacts.DisplayPhoto
מכילות דוגמאות של
אחזור פרטי תמונה. אין סיווג נוחות לאחזור הפריט הראשי
לתמונה הממוזערת של איש קשר גולמי, אבל אפשר לשלוח שאילתה
הטבלה ContactsContract.Data
, בחירה מתוך אנשי הקשר הגולמיים
_ID
,
Photo.CONTENT_ITEM_TYPE
, וגם IS_PRIMARY
כדי למצוא את שורת התמונה הראשית של איש הקשר.
נתוני הפיד החברתי של אדם מסוים עשויים לכלול גם תמונות. קבצים אלה מאוחסנים בקטע הטבלה android.provider.ContactsContract.StreamItemPhotos, מתוארת במידע נוסף מפורט בקטע תמונות של רשתות חברתיות.