שילוב אנשי קשר (ContactsProvider) באפליקציות אנדרואיד

האם אפליקציית האנדרואיד שלך איטית בטעינת אנשי קשר או מציגה כפילויות? אנחנו מפתחים אינטגרציית אנשי קשר באמצעות ContactsProvider, תוך התחשבות במבנה התלת-שכבתי של RawContacts, Contacts ו-Data. הצוות שלנו מספק את הפרויקט במפתח מלא—מביקורת ועד יישום—ומבטיח פעילות יציבה ותמיכה מתמשכת.

פיתוח ותמיכה בכל סוגי היישומים הניידים:

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

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
שילוב אנשי קשר (ContactsProvider) באפליקציות אנדרואיד
פשוט
מ- 1 יום עד 3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    869
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1289
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

שילוב אנשי קשר (ContactsProvider) באפליקציית אנדרואיד

לקוח פנה אלינו עם אפליקציה שקרסה בעת טעינת רשימה של 600 אנשי קשר. הניתוח חשף שאילתה מקוננת ל-Contacts + Phone, שגרמה ל-ANR במכשירים ישנים יותר. ייעלנו את הקוד על ידי מעבר לשאילתה אחת דרך Data URI, וקיצרנו את זמן הטעינה מ-3.5 שניות ל-190 אלפיות השנייה. הלקוח חסך 40% מזמן הפיתוח ונמנע מביקורות שליליות. מצב זה אופייני לפרויקטים שמתעלמים מהמבנה התלת-שכבתי של אנשי קשר באנדרואיד: RawContacts (רשומה מחשבון ספציפי—Google, Telegram, טלפון), Contacts (צירוף של מספר RawContacts), ו-Data (שדות ספציפיים: טלפון, אימייל, תמונה). רוב המפתחים עובדים רק עם הטבלאות Contacts ו-Data, מתעלמים מהצירוף—ובסופו של דבר נתקלים בכפילויות. אנו מציעים אינטגרציה סוהר עם הבטחות ביצועים ואבטחה. הניסיון שלנו: 5+ שנים בפיתוח אנדרואיד ולמעלה מ-100 פרויקטים של ניהול אנשי קשר. קבלו ייעוץ—צרו קשר כדי להעריך את הפרויקט שלכם.

אילו הרשאות נדרשות וכיצד לבקש אותן כראוי?

READ_CONTACTS ו-WRITE_CONTACTS הן הרשאות מסוכנות ויש לבקש אותן בזמן ריצה. ב-Android 11+, נוצר ניואנס: אם המשתמש דוחה את ההרשאה פעמיים, קריאה חוזרת ל-ActivityCompat.requestPermissions() לא תפתח דיאלוג—יש להפנות את המשתמש להגדרות האפליקציה דרך ACTION_APPLICATION_DETAILS_SETTINGS. הניסיון שלנו מראה שטיפול נכון בתרחיש זה מגדיל את שיעור ההמרה של מתן הרשאות ב-40%. ב-Android 13+ (API 33), מופיע דגל לגישה סלקטיבית—המשתמש יכול להעניק גישה רק לחלק מאנשי הקשר. האפליקציה חייבת לעבוד כראוי עם מגבלה זו ולא לצפות לרשימה המלאה.

כיצד להימנע מכפילויות בעבודה עם ContactsProvider?

כפילויות נוצרות כאשר לא משתמשים ב-RawContacts. תמיד צרו RawContact תחילה, ולאחר מכן קשרו אליו נתונים באמצעות withValueBackReference. דוגמה:

val ops = ArrayList<ContentProviderOperation>()
ops.add(
    ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
        .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
        .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
        .build()
)
ops.add(
    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, "Иван Петров")
        .build()
)
ops.add(
    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, "+7 999 123 45 67")
        .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
        .build()
)
context.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)

val ops = ArrayList<ContentProviderOperation>() ops.add( ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null) .build() ) ops.add( 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, "Иван Петров") .build() ) ops.add( 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, "+7 999 123 45 67") .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) .build() ) context.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops) היא פעולה אטומית. אם שלב אחד נכשל, כל העסקה מתבטלת. applyBatch מתייחס ל-withValueBackReference(RAW_CONTACT_ID, 0) מתוך התוצאה של הפעולה הראשונה באצווה.

גישת ביצועים דרך Data URI

במקום שאילתה כפולה, השתמשו בשאילתה אחת ל-_ID עם מסנן MIMETYPE:

val dataCursor = context.contentResolver.query(
    ContactsContract.Data.CONTENT_URI,
    arrayOf(
        ContactsContract.Data.CONTACT_ID,
        ContactsContract.Data.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.Phone.NUMBER
    ),
    "${ContactsContract.Data.MIMETYPE} = ?",
    arrayOf(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE),
    "${ContactsContract.Data.DISPLAY_NAME} ASC"
)
שיטה מספר שאילתות זמן טעינה עבור 1200 אנשי קשר סיכון ANR
נאיבית (שתי שאילתות) 1 + N 3.2 שניות גבוה
מותאמת (Data URI) 1 180 אלפיות השנייה נמוך

בפרויקט אמיתי עם 1200 אנשי קשר, זה קיצר את זמן הטעינה מ-3.2 שניות ל-180 אלפיות השנייה—שיפור של פי 17. אנו מבטיחים גישה זו באפליקציה שלכם.

למה להשתמש ב-Data URI במקום שאילתה כפולה?

כי ברשימה של 500+ אנשי קשר, שאילתה כפולה מקוננת גורמת ל-ANR במכשירים חלשים אם היא מבוצעת על ה-main thread. הפתרון הוא ContactsContract.Data.CONTENT_URI או MIMETYPE עם val dataCursor = context.contentResolver.query( ContactsContract.Data.CONTENT_URI, arrayOf( ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER ), "${ContactsContract.Data.MIMETYPE} = ?", arrayOf(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE), "${ContactsContract.Data.DISPLAY_NAME} ASC" ) . בפרויקטים שלנו, אנו תמיד משתמשים בשאילתה אחת ועיבוד אסינכרוני, מה שמונע הקפאות אפילו עם 2000 אנשי קשר. השוו: הגישה המותאמת יעילה פי 20 בזמן תגובה.

ניואנסים שנשכחים לעיתים קרובות

תמונות אנשי קשר דורשות שאילתה נפרדת דרך CursorLoader. אל תטענו תמונות בשאילתה הראשית—זה משפיע מאוד על הזיכרון ברשימות גדולות. שמרו URI של תמונות במסד הנתונים המקומי שלכם.

תוכנית שלב-אחר-שלב לאינטגרציית ContactsProvider 1. בקשו READ_CONTACTS ו-WRITE_CONTACTS עם טיפול בסירוב. 2. עיצבו את מודל הנתונים: החליטו על סוגי MIME ומבנה RawContacts. 3. הטמיעו קריאה דרך Data URI עם שאילתה אחת. 4. הטמיעו כתיבה דרך applyBatch עם withValueBackReference. 5. הוסיפו שמירת תמונות במטמון וניהול URI. 6. כתבו בדיקות יחידה ובדקו על מכשירים עם גרסאות אנדרואיד שונות.

התהליך שלנו: מביקורת ועד פריסה

שלב משך תוצאה
ניתוח דרישות 0.5 יום מפרט טכני, הערכת עלות
עיצוב ארכיטקטורה 0.5 יום תיעוד, בחירת גישה
הטמעת CRUD יומיים קוד עם בדיקות יחידה
אינטגרציה ובדיקות יום אחד דוח בדיקות
פריסה ותמיכה יום אחד גישה ל-Google Play / הפצה פנימית

מה כלול בעבודה

  • ביקורת על היישום הנוכחי של ContactsProvider שלכם (אם קיים)
  • עיצוב גישה מאובטחת בהתחשב בגרסאות אנדרואיד חדשות
  • הטמעת קריאה, כתיבה, עדכון ומחיקה של אנשי קשר
  • טיפול בהרשאות עם גיבוי להגדרות
  • בדיקות יחידה לפעולות ContentResolver
  • תיעוד אינטגרציה
  • חודש אחד של תמיכה לאחר השחרור

ציר זמן: יומיים עד 5 ימים. העלות מחושבת באופן אישי. הזמינו ביקורת על האפליקציה שלכם—צרו קשר כדי לדון בפרטים. קבלו ייעוץ היום.