التغيير المرتقب
لن تتمكّن التطبيقات التي تستهدف إصدار Android القادم من الكتابة مباشرةً في جهات الاتصال باستخدام إذن WRITE_CONTACTS. بدلاً من ذلك، يمكنك استخدام الأهداف العادية لجهات الاتصال (ACTION_INSERT وACTION_EDIT وACTION_INSERT_OR_EDIT). للحصول على مرجع كامل للتنفيذ، يُرجى الاطّلاع على دليل المطوّر حول كيفية تعديل جهات الاتصال باستخدام الأهداف.
على الأجهزة التي تعمل بإصدار Android القادم، ستعمل هذه الأهداف الثلاثة لجهات الاتصال بشكل متّسق ولن تحتاج إلى أي إذن على الإطلاق. إذا كان تطبيقك يستهدف إصدار Android القادم أو إصدارًا أحدث ويحاول الكتابة في جهات الاتصال مباشرةً، فسيتم رفض عمليات الكتابة هذه وسيؤدي ذلك إلى ظهور خطأ SecurityException أو رفض الإذن. بالنسبة إلى المجموعة الصغيرة من التطبيقات التي تتطلّب وصولاً واسعًا لإنشاء جهات الاتصال وتعديلها، سيتم طرح إذن خاص جديد للوصول إلى التطبيقات، وهو MANAGE_CONTACTS، في الإصدار Android 17 QPR2 (الربع الرابع من عام 2026). سينشر Google Play اليوم إرشادات معدَّلة بشأن الوصول إلى جهات الاتصال، بما في ذلك MANAGE_CONTACTS.
سبب اتّخاذ هذه الإجراءات
في الوقت الحالي، إذا كان تطبيقك يحتاج إلى حفظ جهة اتصال واحدة، قد تطلب إذن WRITE_CONTACTS. لكنّ هذا الإذن يمنح وصولاً واسعًا، ما يسمح للتطبيق بإجراء تغييرات واسعة النطاق على جهات الاتصال على الجهاز في الخلفية، حتى بدون تفاعل المستخدم. لا تحتاج معظم التطبيقات إلى هذا الإذن الواسع النطاق.
ومع توفّر بدائل، وصلتنا ملاحظات منكم تفيد بأنّها يجب أن تكون أكثر اتساقًا في المنظومة المتكاملة. في السابق، كانت أهداف جهات الاتصال تعمل بشكل مختلف من جهاز إلى آخر. أسقطت بعض برامج التحرير البيانات التي أدخلتها، مثل صورة جهة الاتصال. على بعض الأجهزة، كان زر الرجوع يحفظ جهة الاتصال بدون قصد من المستخدم أو كان من الصعب العثور على خيار "إنشاء جهة اتصال جديدة". لذا كان طلب الإذن هو الخيار العقلاني. نحن بصدد حلّ كل هذه المشاكل في إصدار Android القادم، ونطلب من الأجهزة التي تعمل به اتّباع المعايير نفسها.
ما يجب استخدامه بدلاً من ذلك
إضافة جهة اتصال أو تعديلها: استخدام أهداف جهات الاتصال
عند استخدام رسائل Intent هذه، وهي ACTION_INSERT وACTION_EDIT وACTION_INSERT_OR_EDIT، يتولّى النظام تنفيذ المهام الصعبة من خلال تقديم تجربة محرّر جهات اتصال منظَّمة وموحَّدة. يفتح هذا الزر نموذجًا سريعًا على شكل نصف ورقة لإدخال جهات اتصال جديدة، أو يتيح للمستخدم البحث بسهولة عن جهة اتصال حالية وإضافة معلومات إليها. ويمكن للمستخدمين توسيع هذه النافذة بسلاسة لتصبح محرِّرًا بملء الصفحة من أجل ملء المزيد من التفاصيل، وكل ذلك بدون الحاجة إلى منح تطبيقك أذونات تعديل مباشرة. يمكنك الاطّلاع على نماذج تجربة المستخدم المؤقتة أدناه:
الشكل 1: إنشاء جهة اتصال جديدة *تجربة المستخدم ليست نهائية*
الشكل 2: إضافة معلومات إلى جهة اتصال حالية *تجربة المستخدم ليست نهائية*
ملاحظة: قد تعدّل الشركات المصنّعة للأجهزة تجربة المستخدم لتتطابق مع نمط نظام التشغيل، ولكن سيظل السلوك متسقًا.
يمكنك تبسيط عملية الإنشاء بشكل أكبر من خلال تمرير حمولات بيانات اختيارية، تُعرف باسم "الإضافات"، إلى جانب طلبك:
- يقترح
EXTRA_ACCOUNTالحساب الذي يتم حفظ جهة الاتصال فيه، وهو أمر مفيد إذا كان تطبيقك يزامن جهات الاتصال. كانت هذه الميزة الإضافية متاحة من قبل، ولكن كان توفّرها يختلف حسب الجهاز. اعتبارًا من إصدار Android القادم، سيتم توحيد معايير الدعم على جميع الأجهزة. - يُرسل "
EXTRA_PHOTO_URI" صورة لتعبئة صورة جهة الاتصال مسبقًا. يتولّى المحرّر معالجة إذن القراءة لعنوان URI نيابةً عنك. هذه الميزة جديدة في إصدار 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) } إذا كنت تعرف جهة الاتصال التي تريد تعديلها، استخدِم 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) }
|
اختيار جهة اتصال: استخدام أداة "منتقي جهات الاتصال"
إذا كنت بحاجة فقط إلى قراءة جهات الاتصال التي يختارها المستخدم، استخدِم منتقي جهات الاتصال المتاح منذ الإصدار 17 من Android. ولا يتطلّب أي إذن.
تطبيقات المكالمات والمراسلة: استخدام "دليل الأشخاص"
تضيف بعض التطبيقات إجراءات "الاتصال باستخدام…" أو "المراسلة باستخدام…" إلى جهات الاتصال ليتمكّن المستخدمون من بدء مكالمة أو محادثة من تطبيق "الهاتف" أو "جهات الاتصال". إذا كان تطبيقك ينفّذ هذا الإجراء حاليًا من خلال كتابة إدخالات إضافية في جهات اتصال المستخدم، يمكنك الانتقال إلى دليل الأشخاص، الذي سيصل في الإصدار QPR2 من Android (الربع الرابع من عام 2026). وهو دليل نظام جديد ينشر فيه تطبيقك كيفية تواصل المستخدمين مع بعضهم البعض في تطبيقك، بدون تعديل جهات اتصال المستخدم.
أمثلة على كيفية نقل التطبيقات
لمعرفة كيفية عمل هذه البدائل عمليًا، إليك بعض الأمثلة على كيفية تعامل أنواع مختلفة من التطبيقات مع الوصول إلى جهات الاتصال:
| مثال على نوع التطبيق (غير حصري) | مسار نقل البيانات المقترَح |
| تطبيقات التواصل الاجتماعي والدفع من نظير إلى نظير ومشاركة الرحلات | إذا كان تطبيقك يتيح للمستخدمين العثور على الأصدقاء أو تقسيم فاتورة أو مشاركة حالة رحلة، فلن تحتاج إلى الإذن بالاطّلاع على جهات الاتصال على الإطلاق. استخدِم "أداة اختيار جهات الاتصال" لاختيار جهة اتصال لمرة واحدة، وشغِّل ACTION_INSERT باستخدام EXTRA_PHOTO_URI عندما ينقر المستخدم على "حفظ في جهات الاتصال" في ملف شخصي. |
| تطبيقات مسح بطاقات الأعمال ضوئيًا والتواصل في الفعاليات | إذا كان تطبيقك يمسح شارة أو رمز استجابة سريعة ضوئيًا ويحفظ جهة اتصال جديدة، أو يضيف رقم هاتف العمل إلى إدخال زميل حالي، استخدِم ACTION_INSERT أو ACTION_INSERT_OR_EDIT. يملأ محرِّر نصف الصفحة الموحّد الحقول التي تم تحليلها مسبقًا (الاسم والشركة والهاتف والبريد الإلكتروني والصورة) ليتمكّن المستخدم من التحقّق منها وحفظها بنقرة واحدة بدون منح أذونات في الخلفية. |
| تطبيقات المراسلة والمكالمات عبر بروتوكول VoIP | بدلاً من طلب WRITE_CONTACTS لإدخال صفوف مخصّصة "الاتصال باستخدام…" أو "المراسلة باستخدام…" في دفتر عناوين المستخدم، يمكنك نشر البيانات الوصفية لإمكانية الوصول من خلال "دليل الأشخاص" واستخدام ACTION_INSERT عندما يضيف المستخدمون جهة اتصال جديدة من سلسلة محادثات. |
| تطبيقات إدارة علاقات العملاء والمزامنة مع السحابة الإلكترونية للمؤسسات | إذا كان تطبيقك يُجري مزامنة مستمرة لجهات الاتصال في الخلفية في اتجاهين مع حساب على السحابة الإلكترونية أو حساب عمل، حيث لا يمكن عرض واجهة مستخدم لكل سجلّ، يكون تطبيقك مؤهلاً للإفصاح عن 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؟
على الأرجح أنّ هذه المطالبات لن تسبّب لكم أي مشكلة. إذا كان تطبيقك يحفظ جهات الاتصال أو يعدّلها بناءً على طلب المستخدم، فإنّ الأهداف المذكورة أعلاه تغطي احتياجاتك، بدون الحاجة إلى إذن أو نموذج بيان في Play Console.
يُستخدم الإذن MANAGE_CONTACTS للتطبيقات التي تهدف بشكل أساسي إلى إدارة جهات الاتصال، في حال عدم كفاية رسائل Intent. على سبيل المثال:
| تطبيقك… | هل تحتاج إلى MANAGE_CONTACTS؟ |
| يتيح لك حفظ جهة اتصال من محادثة أو بطاقة أعمال أو طلب. | لا، أريد استخدام ACTION_INSERT |
| يضيف رقمًا أو عنوان بريد إلكتروني إلى جهة اتصال حالية. | لا، استخدِم ACTION_INSERT_OR_EDIT أو ACTION_EDIT |
| تتيح للمستخدمين اختيار جهات اتصال لدعوتها أو مشاركة المحتوى معها أو الدفع لها. | لا، أريد استخدام منتقي جهات الاتصال |
| تضيف إجراءات الاتصال أو المراسلة إلى جهات الاتصال. | لا، أريد استخدام "دليل الأشخاص" |
| يحتوي على شاشة تعديل جهات الاتصال التي تحمل علامته التجارية. | لا، لا تكفي الواجهة المخصّصة وحدها للتأهّل |
| هو تطبيق مخصّص لإدارة جهات الاتصال أو بديل لتطبيق Dialer. | من المرجّح أن تكون الإجابة نعم |
| تطبيق لإظهار رقم المتّصل والحماية من المكالمات غير المرغوب فيها يُجري تعديلات مجمّعة على إدخالات دفتر العناوين | من المرجّح أن تكون الإجابة نعم |
| تتم مزامنة جهات الاتصال مع حساب مؤسسة أو حساب على السحابة الإلكترونية في الخلفية. | من المرجّح أن تكون الإجابة نعم |
| يؤدي هذا الإذن إلى الاحتفاظ بنسخة احتياطية من جهات الاتصال أو استعادتها بشكل مجمّع أو نقل البيانات من هاتف إلى آخر. | نعم على الأرجح |
| يضبط نغمات رنين مخصّصة لجهات اتصال فردية. | من المرجّح أن تكون الإجابة نعم |
طريقة العمل:
- "
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 يوضّح سبب عدم كفاية الأهداف للوظيفة الأساسية في تطبيقك.
خطوات نقل البيانات
- ابحث عن جهات الاتصال التي يمكنها الكتابة. ابحث في الرمز عن
WRITE_CONTACTSوContactsContract.RawContacts.CONTENT_URIوContactsContract.Data.CONTENT_URIوapplyBatch(ContactsContract.AUTHORITY, …). - استبدِل كل عملية كتابة يوجّهها المستخدم بهدف:
ACTION_INSERTلجهات الاتصال الجديدة، وACTION_EDITأوACTION_INSERT_OR_EDITللتحديثات. - استخدِم أنواع البيانات العادية فقط في
Insert.DATA. نقل إجراءات المكالمات أو الرسائل إلى "دليل المستخدمين" - حدِّد ما إذا كنت بحاجة فعلاً إلى استخدام
MANAGE_CONTACTSمن خلال الجدول أعلاه. إذا كان الأمر كذلك، فعليك التخطيط لتقديم نموذج البيان في Play Console. - أزِل
WRITE_CONTACTSمن ملف البيان عندما لا يحتاج إليه أي مسار برمجي.
المخطط الزمني
| الوقت | ماذا يحدث |
| 21 أكتوبر 2026 | Google Play يعلن عن سياسة MANAGE_CONTACTS |
| 2026 (الإصدار ربع السنوي الثاني من نظام Android 17 الأساسي) | يتوفّر إذن "MANAGE_CONTACTS" |
| 2027 (إصدار Android القادم) | لم يعُد إذن WRITE_CONTACTS يمنح إمكانية الكتابة للتطبيقات التي تستهدف إصدار Android القادم. توحيد أهداف جهات الاتصال على جميع الأجهزة |
| 2027، وليس قبل إصدار Android القادم | تطلب Play Console من التطبيقات التي تستخدم MANAGE_CONTACTS إرسال بيان |
| 2027، وليس قبل إصدار Android القادم | يجب الالتزام بسياسات Google Play |
الأسئلة الشائعة
- هل يؤثر ذلك في كل تطبيق؟
- لا ينطبق تغيير إيقاف
WRITE_CONTACTSنهائيًا إلا على التطبيقات التي تستهدف إصدار Android القادم وما بعده. تحتفظ التطبيقات التي تستهدف الإصدارات القديمة بسلوكها الحالي، ولكن ستتوفّر أداة تعديل جهات الاتصال الموحّدة الجديدة لجميع التطبيقات التي تعمل على نظام التشغيل الجديد، بغض النظر عن حزمة SDK المستهدَفة.
- لا ينطبق تغيير إيقاف
- هل يمكن لتطبيقي حذف جهات الاتصال باستخدام intent؟
- لا، ليس هناك أي نية لحذف جهات الاتصال. يحذف المستخدمون جهات الاتصال في تطبيق جهات الاتصال، ويمكن للتطبيقات التي تتضمّن
MANAGE_CONTACTSحذف جهات الاتصال مباشرةً.
- لا، ليس هناك أي نية لحذف جهات الاتصال. يحذف المستخدمون جهات الاتصال في تطبيق جهات الاتصال، ويمكن للتطبيقات التي تتضمّن
- لديّ شاشة تعديل جهات الاتصال الخاصة بي. هل يمكنني الاحتفاظ به؟
- فقط إذا كان تطبيقك مؤهلاً لبرنامج
MANAGE_CONTACTS. الرغبة في الحفاظ على تصميم مخصّص ليست سببًا كافيًا بحد ذاتها.
- فقط إذا كان تطبيقك مؤهلاً لبرنامج
- هل يحلّ إذن
MANAGE_CONTACTSمحلّ READ_CONTACTS؟- يتضمّن الإذن
MANAGE_CONTACTSإذن الوصول للقراءة، لذا لست بحاجة إلى طلب الإذنَين معًا، ولكن العديد من التطبيقات مؤهَّلة للحصول على الإذنREAD_CONTACTSالذي لا يتطلّب تعديل جهات الاتصال على الإطلاق. قد تستمر هذه التطبيقات في طلبREAD_CONTACTS.
- يتضمّن الإذن
- ماذا عن المستخدمين الذين لديهم إصدارات Android قديمة؟
- تعمل طلبات جهات الاتصال على الإصدارات القديمة أيضًا، ويتولّى تطبيق جهات الاتصال على الجهاز معالجتها. وستعمل معظم التطبيقات بشكل جيد على جميع الأجهزة التي تستخدم هذه الطلبات. إذا كان تطبيقك متأثرًا بمشكلة محدّدة في الاتساق لا يمكن حلّها إلا في أحدث الإصدارات، يمكنك الاحتفاظ بإذن
WRITE_CONTACTSفي بيانك ضمن نطاق إصدار maxSdkVersion مناسب.
- تعمل طلبات جهات الاتصال على الإصدارات القديمة أيضًا، ويتولّى تطبيق جهات الاتصال على الجهاز معالجتها. وستعمل معظم التطبيقات بشكل جيد على جميع الأجهزة التي تستخدم هذه الطلبات. إذا كان تطبيقك متأثرًا بمشكلة محدّدة في الاتساق لا يمكن حلّها إلا في أحدث الإصدارات، يمكنك الاحتفاظ بإذن
-
أخبار المنتجاتفي مؤتمر Google I/O 2026، أعلنّا عن تحوّل Android من نظام تشغيل إلى نظام ذكي. عرضنا أيضًا كيف يمكنك إنشاء تجارب ذكية بشكلٍ أصلي باستخدام النظام والاستفادة من إمكانات ذكاء Google الاصطناعي في تطبيقاتك.
Jingyu Shi • مدّة القراءة: دقيقتان -
أخبار المنتجاتفي مؤتمر Google I/O لهذا العام، لن نكتفي بالتغييرات المتكررة، بل سنُحدث تحوّلاً جذريًا في طريقة إنشاء التطبيقات. تم تصميم أحدث أدواتنا لتناسب عصر الذكاء الاصطناعي الوكيل، وهي تتضمّن ميزات تعزّز إنتاجيتك كمطوّر لتطبيقات Android وتزيد من فعالية وكلاء الذكاء الاصطناعي الذين تنشرهم في قاعدة الرموز البرمجية.
Matthew Warner • مدّة القراءة: 8 دقائق -
أخبار المنتجاتخلال "عرض Android" اليوم، أعلنّا عن انتقال Android من نظام تشغيل إلى نظام ذكي، ما يوفّر المزيد من الفرص للتفاعل مع تطبيقاتك.
Matthew McCullough • مدّة القراءة: 4 دقائق
يمكنك تلقّي آخر الإحصاءات حول تطوير تطبيقات Android في بريدك الوارد أسبوعيًا.