חדשות על המוצר

דרך אמינה יותר להוסיף ולערוך אנשי קשר ב-Android

משך הקריאה: 6 דקות
לצפייה בפרופיל של רוקסנה אליאבדי ווקר
Roxanna Aliabadi Walker מנהל מוצר, Android

מה עומד להשתנות

אפליקציות שמטרגטות את הגרסה הבאה של Android לא יוכלו יותר לכתוב ישירות לאנשי קשר באמצעות ההרשאה WRITE_CONTACTS. במקום זאת, אתם יכולים להשתמש ב-Intent הרגילים של אנשי הקשר (ACTION_INSERT,‏ ACTION_EDIT ו-ACTION_INSERT_OR_EDIT). כדי לראות הטמעה מלאה של קובץ עזר, אפשר לעיין במדריך למפתחים בנושא שינוי אנשי קשר באמצעות כוונות. 

במכשירים שבהם פועלת הגרסה הבאה של Android, שלוש ה-Intent האלה של אנשי הקשר יפעלו באופן עקבי ולא ידרשו הרשאה בכלל. אם האפליקציה שלכם מטרגטת את הגרסה הבאה של Android או גרסה מאוחרת יותר, ומנסה לכתוב ישירות לאנשי הקשר, פעולות הכתיבה האלה יידחו ויובילו ל-SecurityException או לדחיית הרשאה. ב-Android 17 QPR2 (הרבעון הרביעי של 2026) תהיה הרשאת גישה מיוחדת חדשה לאפליקציות, MANAGE_CONTACTS, לקבוצה הקטנה של אפליקציות שצריכות גישה רחבה כדי ליצור ולשנות אנשי קשר. היום Google Play מפרסמת הנחיות מעודכנות לגבי גישה לאנשי קשר, כולל MANAGE_CONTACTS.

למה אנחנו עושים את זה

נכון לעכשיו, אם האפליקציה צריכה לשמור אפילו איש קשר אחד, יכול להיות שאתם מבקשים את ההרשאה WRITE_CONTACTS. אבל ההרשאה הזו מעניקה גישה רחבה, ומאפשרת לאפליקציה לבצע שינויים נרחבים באנשי הקשר במכשיר ברקע, גם בלי אינטראקציה של המשתמש. רוב האפליקציות לא צריכות הרשאה רחבה כזו.

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

במה אפשר להשתמש במקום זאת

הוספה או עריכה של איש קשר: שימוש בכוונות של אנשי קשר

כשמשתמשים ב-Intent האלה – ACTION_INSERT,‏ ACTION_EDIT ו-ACTION_INSERT_OR_EDIT – המערכת מטפלת בעבודה הקשה ומציגה חוויית עריכה נקייה וסטנדרטית של אנשי הקשר. הוא פותח טופס מהיר של חצי גיליון לרשומות חדשות, או מאפשר למשתמש לחפש בקלות ולהוסיף מידע לאיש קשר קיים. המשתמשים יכולים להרחיב את החלון הזה לעורך במסך מלא כדי למלא פרטים נוספים, בלי שהאפליקציה תצטרך הרשאות כתיבה ישירות. אפשר לראות את הדוגמאות הבאות לממשק המשתמש: 

Figure01_01_Quick_Insert_Half_Sheet_Prefilled.png
צילום מסך 2 – כותרת: דגם של מסך מלא ליצירת איש קשר חדש: צילום מסך של ממשק משתמש זמני ב-Android שבו מוצג עורך אנשי קשר במסך מלא עם בורר דמויות, שם, טלפון ושדות אימייל. העיצוב מסומן בתווית "חוויית המשתמש לא סופית".

איור 1: יצירת איש קשר חדש  *ממשק המשתמש לא סופי*

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

איור 2: הוספת מידע לאיש קשר קיים *ממשק המשתמש לא סופי*


הערה: יצרני מכשירים שונים עשויים לשנות את חוויית המשתמש כך שתתאים לסגנון של מערכת ההפעלה שלהם, אבל ההתנהגות תישאר עקבית.


כדי לייעל עוד יותר את תהליך היצירה, אתם יכולים להעביר מטעני נתונים אופציונליים, שנקראים Extras, לצד ה-Intent:

  • EXTRA_ACCOUNT מציע לאיזה חשבון לשמור את איש הקשר, וזה עוזר אם האפליקציה מסנכרנת אנשי קשר. התוסף הזה כבר היה קיים, אבל התמיכה בו הייתה שונה ממכשיר למכשיר. החל מהגרסה הבאה של Android, התמיכה תהיה אחידה בכל המכשירים.
  • ‫EXTRA_PHOTO_URI מעביר תמונה כדי למלא מראש את התמונה של איש הקשר. העורך מטפל בהרשאת הקריאה של ה-URI בשבילכם. זו תכונה חדשה בגרסה הקרובה של Android, והיא תיתמך בכל הסביבה העסקית.

לפני: כתיבה ישירות באמצעות WRITE_CONTACTS (התוצאה היא SecurityException או דחיית הרשאה ברגע שהאפליקציה מטרגטת את הגרסה הבאה של Android.)

 

// Requires android.permission.WRITE_CONTACTS
fun saveContactDirectly(context: Context, name: String, phone: String, account: Account) {
    val ops = arrayListOf(
        ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type)
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, account.name)
            .build(),
        ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                ContactsContract.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
            )
            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
            .build(),
        ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                ContactsContract.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
            )
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
            .build()
    )
    context.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
}

 

 

אחרי: פתיחת הכלי לעריכת אנשי קשר (לא נדרשת הרשאה.)

 

fun saveContactWithEditor(
    context: Context,
    name: String,
    phone: String,
    account: Account,
    photoUri: Uri
) {
    val intent = Intent(Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI).apply {
        putExtra(ContactsContract.Intents.Insert.NAME, name)
        putExtra(ContactsContract.Intents.Insert.PHONE, phone)
        // Suggest which account the contact is saved to
        putExtra(ContactsContract.Intents.Insert.EXTRA_ACCOUNT, account)
        // New in the upcoming Android release: pre-fill the contact photo
        putExtra(ContactsContract.Intents.Insert.EXTRA_PHOTO_URI, photoUri)
        clipData = ClipData.newRawUri("", photoUri)
        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    }
    context.startActivity(intent)
}

 

לפני: עדכון ישיר של איש קשר קיים

 

// Requires android.permission.WRITE_CONTACTS
fun addPhoneDirectly(context: Context, rawContactId: Long, phone: String) {
    val values = ContentValues().apply {
        put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
        put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
        put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
    }
    context.contentResolver.insert(ContactsContract.Data.CONTENT_URI, values)
}

אחרי: המשתמש יכול לבחור איש קשר לעדכון או ליצור איש קשר חדש

fun addPhoneWithEditor(context: Context, phone: String) {
    val intent = Intent(Intent.ACTION_INSERT_OR_EDIT).apply {
        type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
        putExtra(ContactsContract.Intents.Insert.PHONE, phone)
    }
    context.startActivity(intent)
}

אם אתם כבר יודעים איזה איש קשר לעדכן, השתמשו ב-ACTION_EDIT עם ה-URI של איש הקשר הזה:

fun editKnownContact(context: Context, contactUri: Uri, phone: String) {
    val intent = Intent(Intent.ACTION_EDIT, contactUri).apply {
        putExtra(ContactsContract.Intents.Insert.PHONE, phone)
    }
    context.startActivity(intent)
}

 

בחירת איש קשר: שימוש בכלי לבחירת אנשי קשר

אם אתם צריכים רק לקרוא את אנשי הקשר שהמשתמש בוחר, אתם יכולים להשתמש בכלי לבחירת אנשי קשר, שזמין החל מ-Android 17. הוא לא צריך הרשאה.

אפליקציות לשיחות ואפליקציות הודעות: שימוש במדריך האנשים

אפליקציות מסוימות מוסיפות לאנשי הקשר פעולות כמו "שיחה באמצעות…" או "הודעה באמצעות…", כדי שאנשים יוכלו להתחיל שיחה או צ'אט מאפליקציית "טלפון" או מאפליקציית "אנשי קשר". אם האפליקציה שלכם עושה את זה היום על ידי כתיבת רשומות נוספות באנשי הקשר של המשתמש, עברו אל ספריית אנשי הקשר, שתגיע ל-Android QPR2 (רבעון 4 של 2026). זו ספריית מערכת חדשה שבה האפליקציה מפרסמת איך אנשים יכולים להגיע זה לזה באפליקציה, בלי לערוך את אנשי הקשר של המשתמש.

דוגמאות לאפשרויות העברה של אפליקציות

כדי להבין איך החלופות האלה פועלות בפועל, הנה כמה דוגמאות לאופן שבו אפליקציות מסוגים שונים יכולות לגשת לאנשי הקשר:

סוג אפליקציה לדוגמה (רשימה חלקית).מסלול ההעברה המומלץ
אפליקציות חברתיות, אפליקציות לתשלומים בין אנשים פרטיים ואפליקציות לנסיעות משותפותאם האפליקציה שלכם מאפשרת למשתמשים למצוא חברים, לחלק חשבון או לשתף סטטוס נסיעה, אתם לא צריכים הרשאות גישה לאנשי קשר בכלל. כדי לבחור איש קשר באופן חד-פעמי, משתמשים בכלי לבחירת אנשי קשר, ומפעילים את ACTION_INSERT עם EXTRA_PHOTO_URI כשמשתמש לוחץ על "שמירה באנשי הקשר" בפרופיל.
אפליקציות לסריקת כרטיסי ביקור וליצירת קשרים באירועיםאם האפליקציה סורקת תג או קוד QR ושומרת איש קשר חדש, או מוסיפה מספר טלפון בעבודה לרשומה קיימת של קולגה, צריך להשתמש ב-ACTION_INSERT או ב-ACTION_INSERT_OR_EDIT. העורך הסטנדרטי של חצי הגיליון ממלא מראש את השדות המנותחים (שם, חברה, טלפון, אימייל ותמונה) כדי שהמשתמש יוכל לאמת ולשמור בלחיצה אחת בלי להעניק הרשאות ברקע.
אפליקציות לשיחות ולהעברת הודעות ב-VoIPבמקום לבקש מ-WRITE_CONTACTS להוסיף שורות מותאמות אישית של "שיחה באמצעות…" או "הודעה באמצעות…" לפנקס הכתובות של המשתמש, צריך לפרסם מטא-נתונים של יכולת הגעה (reachability) דרך ספריית המשתמשים ולהשתמש ב-ACTION_INSERT כשמשתמשים מוסיפים איש קשר חדש משרשור צ'אט.
אפליקציות לניהול קשרי לקוחות (CRM) וסנכרון בענן לארגוניםאם האפליקציה מבצעת סנכרון רציף ודו-כיווני של אנשי קשר ברקע עם חשבון בענן או חשבון ארגוני, ולא ניתן להציג למשתמש ממשק Intent לכל רשומה, האפליקציה עומדת בדרישות להצהרה על MANAGE_CONTACTS 

שינויים שצריך לבדוק

  • סוגי נתונים מותאמים אישית לא נתמכים בכלי העריכה. אם מעבירים שורות Insert.DATA עם סוגי MIME שאינם הסוגים הרגילים של ContactsContract.CommonDataKinds, העורך יתעלם מסוגי ה-MIME האלה בלי להציג הודעה.
  • SHOW_OR_CREATE_CONTACT לא מטופל על ידי עורך המערכת. אפליקציות של אנשי קשר שמגיעות עם המכשיר עדיין יכולות לטפל בזה. כדי שההתנהגות תהיה עקבית בכל המכשירים, צריך להשתמש ב-ACTION_INSERT_OR_EDIT.
  • כברירת מחדל, פעולות הכתיבה נכשלות. אחרי שמטרגטים לגרסת Android הבאה, כל כתיבה ישירה בלי MANAGE_CONTACTS תוביל ל-SecurityException or permission denial. בודקים את זה.

האם צריך את MANAGE_CONTACTS?

סביר להניח שלא. אם האפליקציה שומרת או עורכת אנשי קשר כי המשתמש ביקש, ה-Intent שלמעלה מכסה אתכם, בלי הרשאה ובלי הצהרה ב-Play Console.

ההרשאה MANAGE_CONTACTS מיועדת לאפליקציות שהמטרה העיקרית שלהן היא ניהול אנשי קשר, במקרים שבהם ה-intent לא מספיק. לדוגמה:

האפליקציה…צריכים MANAGE_CONTACTS?
שמירת איש קשר מצ'אט, מכרטיס ביקור או מהזמנה.לא, צריך להשתמש ב-ACTION_INSERT
הוספת מספר טלפון או כתובת אימייל לאיש קשר קיים.לא, צריך להשתמש ב-ACTION_INSERT_OR_EDIT או ב-ACTION_EDIT
מאפשר למשתמשים לבחור אנשי קשר כדי להזמין אותם, לשתף איתם או לשלם להם.לא, אני משתמש בכלי לבחירת אנשי קשר
מוסיפה פעולות של שיחות או הודעות לאנשי קשר.לא, אני רוצה להשתמש במדריך המשתמשים
יש לו מסך עריכת אנשי קשר ממותג משלו.לא, ממשק מותאם אישית בלבד לא עומד בדרישות
האפליקציה היא אפליקציה ייעודית לניהול אנשי קשר או אפליקציה שמחליפה את החייגן.כנראה שכן
אפליקציה לזיהוי שיחות ולהגנה מפני ספאם שמעדכנת באופן המוני את הרשומות בפנקס הכתובות.כנראה שכן
מסנכרן אנשי קשר עם חשבון ארגוני או חשבון בענן ברקע.כנראה שכן
מבצעת גיבוי או שחזור של אנשי קשר בכמות גדולה, או העברה של נתונים בין טלפונים.כנראה שכן
מגדירה רינגטונים מותאמים אישית לאנשי קשר ספציפיים.כנראה שכן

איך זה עובד:

  • MANAGE_CONTACTS היא הרשאת גישה מיוחדת לאפליקציות. זו לא תיבת דו-שיח של זמן ריצה. המשתמשים מפעילים את ההגדרה הזו בקטע הגדרות > גישה מיוחדת לאפליקציה > ניהול אנשי קשר.
// Opens Settings > Apps > Special app access > Manage contacts
val intent = Intent(Settings.ACTION_MANAGE_CONTACTS, Uri.fromParts("package", packageName, null))
context.startActivity(intent)
  • היא כוללת קריאה, הוספה, עריכה ומחיקה של אנשי קשר, חשבונות ונתונים של ספריית המשתמשים. אין צורך לבקש גם את READ_CONTACTS.
  • כדי לפרסם ב-Google Play עם MANAGE_CONTACTS, צריך לשלוח הצהרה ב-Play Console ולהסביר למה ה-Intent לא מספיקים לפונקציונליות העיקרית של האפליקציה.

שלבי ההעברה

  • איך מוצאים את אנשי הקשר שכותבים מחפשים בקוד את הערכים WRITE_CONTACTS, ContactsContract.RawContacts.CONTENT_URI, ContactsContract.Data.CONTENT_URI ו-applyBatch(ContactsContract.AUTHORITY, …).
  • מחליפים כל פעולת כתיבה שמונעת על ידי המשתמש ב-Intent: ACTION_INSERT לאנשי קשר חדשים, ו-ACTION_EDIT או ACTION_INSERT_OR_EDIT לעדכונים.
  • השתמשו רק בסוגי נתונים סטנדרטיים ב-Insert.DATA. העברת פעולות של שיחות או הודעות לספריית האנשים.
  • החליטו אם אתם באמת צריכים את MANAGE_CONTACTS בעזרת הטבלה שלמעלה. אם כן, תכננו את ההצהרה ב-Play Console.
  • הסירו את WRITE_CONTACTS מהמניפסט ברגע שאין נתיב קוד שזקוק להרשאה הזו.

ציר הזמן

מתימה קורה בעקבות ההשעיה
‫21 באוקטובר 2026‫Google Play מכריזה על המדיניות בנושא MANAGE_CONTACTS
‫2026 (גרסת פלטפורמה רבעונית 2 של Android 17)ההרשאה MANAGE_CONTACTS הופכת לזמינה
‫2027 (גרסת Android הבאה)ההרשאה WRITE_CONTACTS לא מעניקה יותר גישת כתיבה לאפליקציות שמטרגטות את הגרסה הבאה של Android. כוונות המשתמשים לגבי אנשי קשר הן אחידות בכל המכשירים
‫2027, לא לפני הגרסה הבאה של Androidאפליקציות שמשתמשות בהרשאה MANAGE_CONTACTS נדרשות להגיש הצהרה ב-Play Console
‫2027, לא לפני הגרסה הבאה של Androidחובה לעמוד בדרישות המדיניות של Play

שאלות נפוצות

  • האם זה משפיע על כל אפליקציה?
    • הוצאה משימוש של WRITE_CONTACTS חלה רק על אפליקציות שמטרגטות את הגרסה הבאה של Android ואילך. אפליקציות שמטרגטות גרסאות ישנות יותר שומרות על ההתנהגות הנוכחית שלהן, אבל עורך אנשי הקשר החדש והאחיד יהיה זמין לכל האפליקציות שפועלות במערכת ההפעלה החדשה, בלי קשר ל-SDK המטורגט שלהן.
  • האם האפליקציה שלי יכולה למחוק אנשי קשר באמצעות Intent?
    • לא. אין Intent למחיקת אנשי קשר. המשתמשים מוחקים אנשי קשר באפליקציית אנשי הקשר שלהם. אפליקציות עם MANAGE_CONTACTS יכולות למחוק אנשי קשר ישירות.
  • כבר יש לי מסך משלי לעריכת אנשי קשר. אפשר להשאיר אותו?
    • רק אם האפליקציה עומדת בדרישות של MANAGE_CONTACTS. הרצון לשמור על עיצוב בהתאמה אישית הוא לא סיבה מספיק טובה בפני עצמה.
  • האם MANAGE_CONTACTS מחליף את READ_CONTACTS?
    • MANAGE_CONTACTS כוללת גישת קריאה, כך שאין צורך לבקש את שתיהן, אבל אפליקציות רבות עומדות בדרישות של READ_CONTACTS ולא צריכות לשנות אנשי קשר בכלל. יכול להיות שהאפליקציות האלה ימשיכו לבקש גישה אל READ_CONTACTS.
  • מה לגבי המשתמשים שלי עם גרסאות Android ישנות יותר?
    • ה-intent של אנשי הקשר פועלים גם בגרסאות ישנות יותר, ומטופלים על ידי אפליקציית אנשי הקשר של המכשיר. רוב האפליקציות יפעלו היטב בכל המכשירים באמצעות ה-intent האלה. אם האפליקציה שלכם מושפעת מבעיית עקביות ספציפית שנפתרה רק בגרסאות העדכניות, אתם יכולים להשאיר את ההרשאה WRITE_CONTACTS במניפסט עם maxSdkVersion מתאים.
כותב/ת המסמך:
להמשך קריאה