چه چیزی تغییر میکند
برنامههایی که نسخه آتی Android را هدف قرار میدهند دیگر نمیتوانند بااجازه WRITE_CONTACTS مستقیماً در مخاطبین بنویسند. درعوض، میتوانید از هدفهای مخاطب استاندارد (ACTION_INSERT، ACTION_EDIT، و ACTION_INSERT_OR_EDIT) استفاده کنید. برای پیادهسازی مرجع کامل، راهنمای توسعهدهنده را درباره نحوه اصلاح مخاطبین بااستفاده از هدفها ببینید.
در دستگاههایی که نسخه آتی Android را اجرا میکنند، این سه هدف مخاطب بهطور هماهنگ رفتار خواهند کرد و اصلاً به هیچ اجازهای نیاز ندارند. اگر برنامه شما نسخه آتی Android یا نسخههای جدیدتر را هدف قرار دهد و تلاش کند مستقیماً در مخاطبین بنویسد، این نوشتنها رد خواهد شد و منجر به SecurityException یا رد اجازه خواهد شد. برای مجموعه کوچکی از برنامهها که برای ایجاد و اصلاح مخاطبین به دسترسی گسترده نیاز دارند، اجازه دسترسی ویژه جدیدی به برنامه، MANAGE_CONTACTS، در Android 17 QPR2 (سهماهه چهارم ۲۰۲۶) ارائه میشود. Google Play امروز دستورالعملهای بهروزشدهای را برای دسترسی به مخاطبین، ازجمله MANAGE_CONTACTS، منتشر میکند.
چرا این کار را انجام میدهیم
درحالحاضر، اگر برنامهتان نیاز به ذخیره حتی یک مخاطب داشته باشد، ممکن است WRITE_CONTACTS را درخواست کنید. اما این اجازه دسترسی گستردهای را اعطا میکند و به برنامه اجازه میدهد تغییرات گستردهای در مخاطبین سراسر دستگاه در پسزمینه ایجاد کند، حتی بدون تعامل کاربر. اکثر برنامهها به چنین اجازه گستردهای نیاز ندارند.
درحالیکه جایگزینهایی وجود دارد، از شما شنیدهایم که این جایگزینها باید در سراسر بومسازگان استانداردتر شوند. قبلاً، هدفهای مخاطب در دستگاههای مختلف متفاوت عمل میکردند. برخیاز ویرایشگرها دادههایی را که وارد کردهاید، مثل عکس مخاطب، حذف کردند. در برخیاز دستگاهها، دکمه برگشتن مخاطب را بدون قصد کاربر ذخیره میکرد یا گزینه «ایجاد مخاطب جدید» بهسختی پیدا میشد. بنابراین درخواست اجازه انتخاب منطقی بود. ما همه این مشکلات را در نسخه آتی Android برطرف میکنیم و دستگاههایی را که از آن استفاده میکنند ملزم میکنیم از همین استانداردها پیروی کنند.
بهجای آن از چه چیزی استفاده کنید
افزودن یا ویرایش مخاطب: از هدفهای مخاطب استفاده کنید
وقتی از این هدفها (ACTION_INSERT، ACTION_EDIT، و ACTION_INSERT_OR_EDIT) استفاده میکنید، سیستم با ارائه تجربه ویرایشگر مخاطب تمیز و استاندارد، کارهای سنگین را انجام میدهد. این دکمه فرم نیمبرگ سریعی را برای ورودیهای جدید باز میکند یا به کاربر اجازه میدهد بهراحتی اطلاعاتی را جستجو کند و به مخاطب موجود اضافه کند. کاربران میتوانند بهطور یکپارچه این را به یک ویرایشگر تمامصفحه گسترش دهند تا جزئیات بیشتری را پر کنند، بدون اینکه برنامه شما به اجازههای نوشتن مستقیم نیاز داشته باشد. نمونههای آزمایشی تجربه کاربری را در زیر ببینید:
شکل ۱: ایجاد مخاطب جدید *تجربه کاربری نهایی نیست*
شکل ۲: افزودن اطلاعات به مخاطب موجود *تجربه کاربری نهایی نیست*
توجه: سازندگان مختلف دستگاه ممکن است تجربه کاربری را برای مطابقت با سبک سیستمعامل خود تغییر دهند، اما رفتار ثابت باقی خواهد ماند.
میتوانید با ارسال بار دادههای اختیاری، که بهعنوان «موارد اضافی» شناخته میشوند، در کنار قصدتان، فرایند ایجاد را بیشتر ساده کنید:
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) }
|
انتخاب مخاطب: استفاده از «انتخابگر مخاطب»
اگر فقط لازم است مخاطبینی را که کاربر انتخاب میکند بخوانید، از انتخابگر مخاطب استفاده کنید که از Android 17 دردسترس است. به هیچ اجازهای نیاز ندارد.
برنامههای تماس و پیامرسانی: از «فهرست افراد» استفاده کنید
برخیاز برنامهها کنشهای «تماس با…» یا «پیام با…» را به مخاطبین اضافه میکنند تا افراد بتوانند از برنامه «تلفن» یا «مخاطبین» تماس یا گپ شروع کنند. اگر برنامه شما امروز این کار را با نوشتن ورودیهای اضافی در مخاطبین کاربر انجام میدهد، به فهرست راهنمای افراد بروید که در Android QPR2 (سهماهه چهارم ۲۰۲۶) ارائه میشود. این یک دایرکتوری سیستم جدید است که در آن برنامه شما نحوه دسترسی افراد به یکدیگر را در برنامه شما منتشر میکند، بدون اینکه مخاطبین کاربر را ویرایش کند.
نمونههایی از نحوه انتقال برنامهها
برای اینکه ببینید این جایگزینها در عمل چگونه کار میکنند، در اینجا چند نمونه از نحوه رویکرد انواع مختلف برنامهها به دسترسی به مخاطبین آورده شده است:
| نوع برنامه نمونه (غیرانحصاری). | مسیر انتقال توصیهشده |
| برنامههای اجتماعی، پرداخت همتا به همتا، و همپیمایی | اگر برنامهتان به کاربران اجازه میدهد دوست پیدا کنند، صورتحساب را تقسیم کنند، یا وضعیت سفر را همرسانی کنند، اصلاً به اجازه مخاطبین نیاز ندارید. از «انتخابگر مخاطب» برای انتخاب یکباره مخاطب استفاده کنید و وقتی کاربر روی «ذخیره در مخاطبین» در نمایه تکضرب میزند، ACTION_INSERT را با EXTRA_PHOTO_URI راهاندازی کنید. |
| اسکنر کارت کسبوکار و برنامههای شبکهسازی رویداد | اگر برنامهتان نشان یا رمزینه پاسخسریع را اسکن میکند و مخاطب جدیدی ذخیره میکند – یا شماره تلفن کاری را به ورودی همکار موجود اضافه میکند – از ACTION_INSERT یا ACTION_INSERT_OR_EDIT استفاده کنید. ویرایشگر نیمبرگ استانداردشده فیلدهای تجزیهشده (نام، شرکت، تلفن، ایمیل، و عکس) را ازقبل تکمیل میکند تا کاربر بتواند با یک تکضرب و بدون اعطای اجازههای پسزمینه، اطلاعات را تأیید و ذخیره کند. |
| برنامههای پیامرسانی و تماس VoIP | بهجای درخواست از WRITE_CONTACTS برای تزریق ردیفهای سفارشی «تماس با…» یا «پیام با…» در دفترچه تلفن کاربر، فرادادههای دسترسیپذیری را ازطریق «فهرست راهنمای افراد» منتشر کنید و وقتی کاربران مخاطب جدیدی را از رشته گپ اضافه میکنند، از ACTION_INSERT استفاده کنید. |
| برنامههای همگامسازی ابری و CRM سازمانی | اگر برنامهتان همگامسازی مخاطب پسزمینه دوطرفه و مداوم با حساب ابری یا سازمانی انجام میدهد – که در آن درخواست از کاربر با میانای قصد برای هر سابقه امکانپذیر نیست – برنامهتان واجدشرایط اعلام MANAGE_CONTACTS است |
تغییراتی که باید بررسی شود
- انواع دادههای سفارشی در ویرایشگر پشتیبانی نمیشوند. اگر ردیفهای
Insert.DATAرا با انواع رسانه غیر از انواع استانداردContactsContract.CommonDataKindsارسال کنید، ویرایشگر آن انواع رسانه را بدون اطلاع نادیده میگیرد. SHOW_OR_CREATE_CONTACTتوسط ویرایشگر سیستم مدیریت نمیشود. برنامههای مخاطبین که با دستگاه ارائه میشوند همچنان میتوانند آن را مدیریت کنند. برای رفتار یکسان در همه دستگاهها، ازACTION_INSERT_OR_EDITاستفاده کنید.- نوشتن بهطور پیشفرض ناموفق است. وقتی نسخه آتی Android را هدف قرار میدهید، هرگونه نوشتن مستقیم بدون
MANAGE_CONTACTSمنجر بهSecurityException or permission denialمیشود. آزمایش کنید.
آیا به MANAGE_CONTACTS نیاز دارم؟
احتمالاً نه. اگر برنامهتان مخاطبین را بهدرخواست کاربر ذخیره یا ویرایش میکند، هدفهای بالا شما را پوشش میدهند، بدون اینکه به اجازه و اظهارنامه «کنسول Play» نیاز باشد.
MANAGE_CONTACTS برای برنامههایی است که هدف اصلیشان مدیریت مخاطبین است و هدفها کافی نیستند. برای مثال:
| برنامه شما… | به 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» ارسال کنید و توضیح دهید چرا هدفها برای عملکرد اصلی برنامهتان کافی نیستند.
مراحل انتقال
- نوشتههای مخاطب را پیدا کنید. کدتان را برای
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» خود را برنامهریزی کنید. - وقتی هیچ مسیر کدی به
WRITE_CONTACTSنیاز نداشت، آن را از مانیفست بردارید.
خط زمان
| زمان | چه اتفاقی میافتد |
| ۲۱ اکتبر ۲۰۲۶ | Google Play خطمشی MANAGE_CONTACTS را اعلام میکند |
| ۲۰۲۶ (Android 17 Quarterly Platform Release 2) | اجازه MANAGE_CONTACTS دردسترس قرار میگیرد |
| ۲۰۲۷ (نسخه آتی Android) | WRITE_CONTACTS دیگر دسترسی نوشتن را به برنامههایی که نسخه آتی Android را هدف قرار میدهند اعطا نمیکند. هدفهای مخاطب در همه دستگاهها استاندارد شده است |
| ۲۰۲۷، نه زودتر از انتشار نسخه آتی Android | «کنسول Play» از برنامههایی که از MANAGE_CONTACTS استفاده میکنند میخواهد اظهارنامه ارسال کنند |
| ۲۰۲۷، نه زودتر از انتشار نسخه آتی Android | رعایت خطمشی Play الزامی است |
پرسشگان
- آیا این موضوع بر همه برنامهها تأثیر میگذارد؟
- تغییر منسوخ شدن
WRITE_CONTACTSفقط برای برنامههایی اعمال میشود که نسخه آتی Android و نسخههای بعداز آن را هدف قرار میدهند. برنامههایی که نسخههای قدیمیتر را هدف قرار میدهند رفتار فعلیشان را حفظ میکنند، اما ویرایشگر مخاطب استانداردشده جدید برای همه برنامههایی که در سیستمعامل جدید اجرا میشوند دردسترس خواهد بود، صرفنظر از اینکه کیت توسعه نرمافزار هدف آنها چه باشد.
- تغییر منسوخ شدن
- آیا برنامهام میتواند مخاطبین را با قصد حذف کند؟
- نه. قصدی برای حذف مخاطبین وجود ندارد. کاربران مخاطبین را در برنامه مخاطبین خود حذف میکنند. برنامههای دارای
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 • ۸ دقیقه خواندن -
اخبار محصولهمانطور که امروز در The Android Show اعلام شد، Android درحال گذار از یک سیستمعامل به یک سیستم هوشمند است و فرصتهای بیشتری برای تعامل با برنامههایتان ایجاد میکند.
Matthew McCullough • زمان خواندن: ۴ دقیقه
جدیدترین اطلاعات آماری توسعه Android را بهصورت هفتگی در صندوق ورودیتان دریافت کنید.