اصلاح مخاطبین بااستفاده از هدف‌ها

این درس به شما نشان می‌دهد که چگونه از Intent برای درج مخاطب جدید یا اصلاح داده‌های مخاطب استفاده کنید. به‌جای دسترسی مستقیم به «ارائه‌دهنده مخاطبین»، Intent برنامه مخاطبین را راه‌اندازی می‌کند که Activity مناسب را اجرا می‌کند. برای کنش‌های اصلاحی شرح‌داده‌شده در این درس، اگر داده‌های گسترش‌یافته را در Intent ارسال کنید، این داده‌ها در واسط کاربری Activity که شروع شده است وارد می‌شود.

استفاده از Intent برای درج یا به‌روزرسانی یک مخاطب، روش ترجیحی برای اصلاح «ارائه‌دهنده مخاطبین» است، به دلایل زیر:

  • این کار باعث صرفه‌جویی در زمان و تلاش شما برای توسعه واسط کاربری و کد خودتان می‌شود.
  • این کار از بروز خطاهای ناشی از اصلاحاتی که از قوانین «ارائه‌دهنده مخاطبین» پیروی نمی‌کنند جلوگیری می‌کند.
  • این کار تعداد اجازه‌هایی را که باید درخواست کنید کاهش می‌دهد. برنامه شما برای نوشتن در «ارائه‌دهنده مخاطبین» به اجازه نیاز ندارد، زیرا تغییرات را به برنامه مخاطبین واگذار می‌کند که قبلاً این اجازه را دارد.

درج مخاطب جدید بااستفاده از قصد

اغلب می‌خواهید به کاربر اجازه دهید وقتی برنامه‌تان داده‌های جدیدی دریافت می‌کند، مخاطب جدیدی درج کند. برای مثال، برنامه مرور رستوران می‌تواند به کاربران اجازه دهد رستوران را به‌عنوان مخاطب اضافه کنند، همان‌طور که آن را مرور می‌کنند. برای انجام این کار بااستفاده از هدف، هدف را بااستفاده از بیشترین داده‌ای که دردسترس دارید ایجاد کنید، سپس هدف را به برنامه مخاطبین ارسال کنید.

درج مخاطب بااستفاده از برنامه مخاطبین، مخاطب خام جدیدی را در جدول ContactsContract.RawContacts «ارائه‌دهنده مخاطبین» درج می‌کند. درصورت لزوم، برنامه مخاطبین از کاربران می‌خواهد نوع حساب و حسابی را که باید هنگام ایجاد مخاطب خام استفاده شود انتخاب کنند. برنامه مخاطبین همچنین اگر مخاطب خام ازقبل وجود داشته باشد به کاربران اطلاع می‌دهد. سپس کاربران گزینه لغو درج را دارند که در این صورت هیچ مخاطبی ایجاد نمی‌شود. برای کسب اطلاعات بیشتر درباره مخاطبین خام، به راهنمای API ارائه‌دهنده مخاطبین مراجعه کنید.

ایجاد قصد

برای شروع، شیء Intent جدیدی با کنش Intents.Insert.ACTION ایجاد کنید. نوع MIME را روی RawContacts.CONTENT_TYPE تنظیم کنید. برای مثال:

کاتلین

...
// Creates a new Intent to insert a contact
val intent = Intent(ContactsContract.Intents.Insert.ACTION).apply {
    // Sets the MIME type to match the Contacts Provider
    type = ContactsContract.RawContacts.CONTENT_TYPE
}

جاوا

...
// Creates a new Intent to insert a contact
Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
// Sets the MIME type to match the Contacts Provider
intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);

اگر ازقبل جزئیاتی برای مخاطب دارید، مثل شماره تلفن یا نشانی ایمیل، می‌توانید آن‌ها را به‌عنوان داده‌های گسترش‌یافته در هدف درج کنید. برای مقدار کلید، از ثابت مناسب از Intents.Insert استفاده کنید. برنامه مخاطبین داده‌ها را در صفحه درج خود نمایش می‌دهد و به کاربران اجازه می‌دهد ویرایش‌ها و افزودنی‌های بیشتری انجام دهند.

کاتلین

private var emailAddress: EditText? = null
private var phoneNumber: EditText? = null
...
/* Assumes EditText fields in your UI contain an email address
 * and a phone number.
 *
 */
emailAddress = findViewById(R.id.email)
phoneNumber = findViewById(R.id.phone)
...
/*
 * Inserts new data into the Intent. This data is passed to the
 * contacts app's Insert screen
 */
intent.apply {
    // Inserts an email address
    putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress?.text)
    /*
     * In this example, sets the email type to be a work email.
     * You can set other email types as necessary.
     */
    putExtra(
            ContactsContract.Intents.Insert.EMAIL_TYPE,
            ContactsContract.CommonDataKinds.Email.TYPE_WORK
    )
    // Inserts a phone number
    putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber?.text)
    /*
     * In this example, sets the phone type to be a work phone.
     * You can set other phone types as necessary.
     */
    putExtra(
            ContactsContract.Intents.Insert.PHONE_TYPE,
            ContactsContract.CommonDataKinds.Phone.TYPE_WORK
    )
}

جاوا

private EditText emailAddress = null;
private EditText phoneNumber = null;
...
/* Assumes EditText fields in your UI contain an email address
 * and a phone number.
 *
 */
emailAddress = (EditText) findViewById(R.id.email);
phoneNumber = (EditText) findViewById(R.id.phone);
...
/*
 * Inserts new data into the Intent. This data is passed to the
 * contacts app's Insert screen
 */
// Inserts an email address
intent.putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress.getText())
/*
 * In this example, sets the email type to be a work email.
 * You can set other email types as necessary.
 */
      .putExtra(ContactsContract.Intents.Insert.EMAIL_TYPE,
            ContactsContract.CommonDataKinds.Email.TYPE_WORK)
// Inserts a phone number
      .putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber.getText())
/*
 * In this example, sets the phone type to be a work phone.
 * You can set other phone types as necessary.
 */
      .putExtra(ContactsContract.Intents.Insert.PHONE_TYPE,
            ContactsContract.CommonDataKinds.Phone.TYPE_WORK);

پس‌از ایجاد Intent، آن را با فراخوانی startActivity() ارسال کنید.

کاتلین

    /* Sends the Intent
     */
    startActivity(intent)

جاوا

    /* Sends the Intent
     */
    startActivity(intent);

این فراخوانی صفحه‌ای را در برنامه مخاطبین باز می‌کند که به کاربران اجازه می‌دهد مخاطب جدیدی وارد کنند. نوع حساب و نام حساب مخاطب در بالای صفحه فهرست شده است. وقتی کاربران داده‌ها را وارد می‌کنند و روی تمام کلیک می‌کنند، فهرست مخاطبین برنامه مخاطبین ظاهر می‌شود. کاربران با کلیک کردن روی برگشت به برنامه شما برمی‌گردند.

ویرایش مخاطب موجود بااستفاده از قصد

ویرایش مخاطب موجود بااستفاده از Intent زمانی مفید است که کاربر قبلاً مخاطب موردنظر را انتخاب کرده باشد. برای مثال، برنامه‌ای که مخاطبین دارای نشانی پستی اما فاقد کد پستی را پیدا می‌کند می‌تواند به کاربران این امکان را بدهد که کد پستی را جستجو کنند و سپس آن را به مخاطب اضافه کنند.

برای ویرایش مخاطب موجود بااستفاده از هدف، از روشی مشابه درج مخاطب استفاده کنید. قصدی را همان‌طور که در بخش درج مخاطب جدید بااستفاده از قصد شرح داده شده است ایجاد کنید، اما Contacts.CONTENT_LOOKUP_URI مخاطب و نوع MIME Contacts.CONTENT_ITEM_TYPE را به قصد اضافه کنید. اگر می‌خواهید مخاطب را با جزئیاتی که ازقبل دارید ویرایش کنید، می‌توانید آن‌ها را در داده‌های گسترش‌یافته هدف قرار دهید. توجه داشته باشید که برخی‌از ستون‌های نام را نمی‌توان بااستفاده از قصد ویرایش کرد؛ این ستون‌ها در بخش خلاصه مرجع میانای برنامه‌سازی کاربردی برای کلاس ContactsContract.Contacts زیر عنوان «به‌روزرسانی» فهرست شده‌اند.

درنهایت، قصد را ارسال کنید. در پاسخ، برنامه مخاطبین صفحه ویرایش را نمایش می‌دهد. وقتی کاربر ویرایش را تمام می‌کند و ویرایش‌ها را ذخیره می‌کند، برنامه مخاطبین فهرست مخاطبین را نمایش می‌دهد. وقتی کاربر روی برگشت کلیک می‌کند، برنامه شما نمایش داده می‌شود.

قصد را ایجاد کنید

برای ویرایش مخاطب، با Intent(action) تماس بگیرید تا قصدی با کنش ACTION_EDIT ایجاد کنید. ‫setDataAndType() را فراخوانی کنید تا مقدار داده را برای قصد به Contacts.CONTENT_LOOKUP_URI مخاطب و نوع MIME را به نوع MIME‏ Contacts.CONTENT_ITEM_TYPE تنظیم کنید؛ چون فراخوانی setType() مقدار داده فعلی را برای Intent بازنویسی می‌کند، باید داده و نوع MIME را هم‌زمان تنظیم کنید.

برای دریافت Contacts.CONTENT_LOOKUP_URI مخاطب، Contacts.getLookupUri(id, lookupkey) را با مقادیر Contacts._ID و Contacts.LOOKUP_KEY مخاطب به‌عنوان آرگومان فراخوانی کنید.

توجه: مقدار LOOKUP_KEY مخاطب شناسه‌ای است که باید برای بازیابی مخاطب استفاده کنید. این شناسه ثابت می‌ماند، حتی اگر ارائه‌دهنده شناسه ردیف مخاطب را برای مدیریت عملیات داخلی تغییر دهد.

قطعه کد زیر نحوه ایجاد قصد را نشان می‌دهد:

کاتلین

    // The Cursor that contains the Contact row
    var mCursor: Cursor? = null
    // The index of the lookup key column in the cursor
    var lookupKeyIndex: Int = 0
    // The index of the contact's _ID value
    var idIndex: Int = 0
    // The lookup key from the Cursor
    var currentLookupKey: String? = null
    // The _ID value from the Cursor
    var currentId: Long = 0
    // A content URI pointing to the contact
    var selectedContactUri: Uri? = null
    ...
    /*
     * Once the user has selected a contact to edit,
     * this gets the contact's lookup key and _ID values from the
     * cursor and creates the necessary URI.
     */
    mCursor?.apply {
        // Gets the lookup key column index
        lookupKeyIndex = getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)
        // Gets the lookup key value
        currentLookupKey = getString(lookupKeyIndex)
        // Gets the _ID column index
        idIndex = getColumnIndex(ContactsContract.Contacts._ID)
        currentId = getLong(idIndex)
        selectedContactUri = ContactsContract.Contacts.getLookupUri(currentId, mCurrentLookupKey)
    }

    // Creates a new Intent to edit a contact
    val editIntent = Intent(Intent.ACTION_EDIT).apply {
        /*
         * Sets the contact URI to edit, and the data type that the
         * Intent must match
         */
        setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE)
    }

جاوا

    // The Cursor that contains the Contact row
    public Cursor mCursor;
    // The index of the lookup key column in the cursor
    public int lookupKeyIndex;
    // The index of the contact's _ID value
    public int idIndex;
    // The lookup key from the Cursor
    public String currentLookupKey;
    // The _ID value from the Cursor
    public long currentId;
    // A content URI pointing to the contact
    Uri selectedContactUri;
    ...
    /*
     * Once the user has selected a contact to edit,
     * this gets the contact's lookup key and _ID values from the
     * cursor and creates the necessary URI.
     */
    // Gets the lookup key column index
    lookupKeyIndex = mCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);
    // Gets the lookup key value
    currentLookupKey = mCursor.getString(lookupKeyIndex);
    // Gets the _ID column index
    idIndex = mCursor.getColumnIndex(ContactsContract.Contacts._ID);
    currentId = mCursor.getLong(idIndex);
    selectedContactUri =
            Contacts.getLookupUri(currentId, mCurrentLookupKey);
    ...
    // Creates a new Intent to edit a contact
    Intent editIntent = new Intent(Intent.ACTION_EDIT);
    /*
     * Sets the contact URI to edit, and the data type that the
     * Intent must match
     */
    editIntent.setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE);

افزودن پرچم پیمایش

در Android 4.0 (نسخه میانای برنامه‌سازی کاربردی ۱۴) و نسخه‌های جدیدتر، مشکلی در برنامه مخاطبین باعث پیمایش نادرست می‌شود. وقتی برنامه‌تان هدف ویرایش را به برنامه مخاطبین ارسال می‌کند و کاربران مخاطبی را ویرایش و ذخیره می‌کنند، وقتی روی برگشت کلیک می‌کنند، صفحه فهرست مخاطبین را می‌بینند. برای برگشتن به برنامه شما، باید روی موارد اخیر کلیک کند و برنامه شما را انتخاب کند.

برای حل این مشکل در Android نسخه ۴.۰.۳ (میانای برنامه‌سازی کاربردی نسخه ۱۵) و بالاتر، کلید داده گسترش‌یافته finishActivityOnSaveCompleted را با مقدار true به هدف اضافه کنید. نسخه‌های Android قبل‌از Android 4.0 این کلید را می‌پذیرند، اما تأثیری ندارد. برای تنظیم داده‌های گسترش‌یافته، کارهای زیر را انجام دهید:

کاتلین

    // Sets the special extended data for navigation
    editIntent.putExtra("finishActivityOnSaveCompleted", true)

جاوا

    // Sets the special extended data for navigation
    editIntent.putExtra("finishActivityOnSaveCompleted", true);

افزودن داده‌های گسترده دیگر

برای افزودن داده‌های گسترده بیشتر به Intent، putExtra() را به‌دلخواه فراخوانی کنید. بااستفاده از مقادیر کلید مشخص‌شده در Intents.Insert می‌توانید داده‌های گسترده را برای فیلدهای مخاطب رایج اضافه کنید. به‌خاطر داشته باشید که برخی‌از ستون‌ها در جدول ContactsContract.Contacts قابل‌اصلاح نیستند. این ستون‌ها در بخش خلاصه مرجع میانای برنامه‌سازی کاربردی برای کلاس ContactsContract.Contacts تحت عنوان «به‌روزرسانی» فهرست شده‌اند.

ارسال قصد

درنهایت، قصدی را که ساخته‌اید ارسال کنید. برای مثال:

کاتلین

    // Sends the Intent
    startActivity(editIntent)

جاوا

    // Sends the Intent
    startActivity(editIntent);

به کاربران اجازه دهید بااستفاده از قصد، درج یا ویرایش را انتخاب کنند

می‌توانید به کاربران اجازه دهید با ارسال Intent با کنش ACTION_INSERT_OR_EDIT، انتخاب کنند که مخاطبی را درج کنند یا مخاطب موجودی را ویرایش کنند. برای مثال، برنامه کارخواه ایمیل می‌تواند به کاربران اجازه دهد نشانی ایمیل ورودی را به مخاطب جدیدی اضافه کنند، یا آن را به‌عنوان نشانی اضافی برای مخاطب موجود اضافه کنند. نوع MIME را برای این هدف روی Contacts.CONTENT_ITEM_TYPE تنظیم کنید، اما URI داده را تنظیم نکنید.

وقتی این هدف را ارسال می‌کنید، برنامه مخاطبین فهرستی از مخاطبین را نمایش می‌دهد. کاربران می‌توانند مخاطب جدیدی را درج کنند یا مخاطب موجودی را انتخاب و آن را ویرایش کنند. هر فیلد داده گسترش‌یافته‌ای که به هدف اضافه می‌کنید، صفحه‌ای را که ظاهر می‌شود پر می‌کند. می‌توانید از هرکدام از مقادیر کلیدی مشخص‌شده در Intents.Insert استفاده کنید. تکه‌کد زیر نحوه ساختن و ارسال قصد را نشان می‌دهد:

کاتلین

    // Creates a new Intent to insert or edit a contact
    val intentInsertEdit = Intent(Intent.ACTION_INSERT_OR_EDIT).apply {
        // Sets the MIME type
        type = ContactsContract.Contacts.CONTENT_ITEM_TYPE
    }
    // Add code here to insert extended data, if desired

    // Sends the Intent with an request ID
    startActivity(intentInsertEdit)

جاوا

    // Creates a new Intent to insert or edit a contact
    Intent intentInsertEdit = new Intent(Intent.ACTION_INSERT_OR_EDIT);
    // Sets the MIME type
    intentInsertEdit.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
    // Add code here to insert extended data, if desired
    ...
    // Sends the Intent with an request ID
    startActivity(intentInsertEdit);