تعديل جهات الاتصال باستخدام الأغراض

يوضّح لك هذا الدرس كيفية استخدام Intent لإدراج جهة اتصال جديدة أو تعديل بيانات جهة اتصال. بدلاً من الوصول إلى مقدّم جهات الاتصال مباشرةً، يبدأ Intent تطبيق جهات الاتصال الذي يشغّل Activity المناسب. وفيما يتعلق بإجراءات التعديل الموضحة في هذا الدرس، إذا أرسلت بيانات موسّعة في Intent، سيتم إدخالها في واجهة مستخدم Activity التي تم تشغيلها.

من المفضّل استخدام Intent لإدراج جهة اتصال واحدة أو تعديلها. لتعديل "موفر جهات الاتصال"، للأسباب التالية:

  • فهو يوفّر عليك الوقت والجهد المبذولَين في تطوير واجهة المستخدم والرموز البرمجية.
  • يتجنب تقديم أخطاء ناجمة عن تعديلات لا تتبع قواعد موفّر جهات الاتصال.
  • يقلل عدد الأذونات التي تحتاج إلى طلبها. لا يحتاج تطبيقك إلى إذن للكتابة في مقدّم جهات الاتصال، لأنّه يفوّض التعديلات إلى تطبيق جهات الاتصال، الذي يملك هذا الإذن من قبل.

إدراج جهة اتصال جديدة باستخدام هدف

غالبًا ما تريد السماح للمستخدم بإدخال جهة اتصال جديدة عندما يتلقّى تطبيقك بيانات جديدة. على سبيل المثال، يمكن أن يسمح تطبيق مراجعات المطاعم للمستخدمين بإضافة المطعم كجهة اتصال أثناء إجراء المراجعة. ولإجراء ذلك باستخدام هدف، أنشِئه باستخدام أكبر قدر ممكن من البيانات لديك. ثم إرسال intent إلى تطبيق جهات الاتصال.

يؤدي إدراج جهة اتصال باستخدام تطبيق جهات الاتصال إلى إدراج جهة اتصال أولية جديدة في جدول ContactsContract.RawContacts الخاص بموفِّر جهات الاتصال . إذا لزم الأمر، يطلب تطبيق جهات الاتصال من المستخدمين نوع الحساب والحساب لاستخدامهما عند إنشاء البيانات الأولية جهة اتصال. ويُرسِل تطبيق جهات الاتصال أيضًا إشعارًا إلى المستخدمين إذا كانت جهة الاتصال الأولية متوفّرة من قبل. بعد ذلك، حصل المستخدمون على خيار إلغاء الإدراج، وفي هذه الحالة لا يتم إنشاء جهة اتصال. للتعلّم المزيد حول جهات الاتصال الأولية، راجع مزوِّد جهات الاتصال دليل واجهة برمجة التطبيقات.

إنشاء نية

للبدء، أنشئ عنصرًا جديدًا من النوع Intent باستخدام الإجراء Intents.Insert.ACTION. اضبط نوع MIME على RawContacts.CONTENT_TYPE. مثلاً:

Kotlin

...
// 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
}

Java

...
// 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 يعرض تطبيق جهات الاتصال البيانات في شاشة الإدراج، ما يسمح للمستخدمين بإجراء المزيد من التعديلات والإضافات.

Kotlin

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
    )
}

Java

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()

Kotlin

    /* Sends the Intent
     */
    startActivity(intent)

Java

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

تفتح هذه المكالمة شاشة في تطبيق جهات الاتصال تسمح للمستخدمين بإدخال جهة اتصال جديدة. تشير رسالة الأشكال البيانية ونوع الحساب واسم الحساب لجهة الاتصال أعلى الشاشة. بعد أن يُدخِل المستخدمون البيانات وينقرون على تم، تظهر قائمة جهات الاتصال في تطبيق جهات الاتصال. يعود المستخدمون إلى تطبيقك بالنقر على رجوع.

تعديل جهة اتصال حالية باستخدام هدف

يكون تعديل جهة اتصال حالية باستخدام Intent مفيدًا إذا كان المستخدم قد اختار جهة اتصال تهمّه. على سبيل المثال، أحد التطبيقات التي يعثر على جهات الاتصال التي تحتوي عناوين بريدية ولكن تفتقر إلى رمز بريدي إلى أن تمنح المستخدمين خيار البحث عن الرمز ثم إضافته إلى جهة الاتصال.

لتعديل جهة اتصال حالية باستخدام هدف، استخدِم إجراءً مشابهًا إدراج جهة اتصال. أنشئ نية كما هو موضّح في القسم إدراج جهة اتصال جديدة باستخدام نية، ولكن أضِف Contacts.CONTENT_LOOKUP_URI جهة الاتصال وContacts.CONTENT_ITEM_TYPE نوع MIME إلى النية. إذا أردت تعديل جهة الاتصال من خلال تقديم تفاصيل يمكنك وضعها بالفعل في البيانات الموسّعة الخاصة بالهدف. لاحظ أن بعض لا يمكن تعديل أعمدة الأسماء باستخدام إجراء. يتم سرد هذه الأعمدة في ملخص في مرجع واجهة برمجة التطبيقات للفئة ContactsContract.Contacts تحت العنوان "تحديث".

أخيرًا، أرسل النية. وفي ردّ على ذلك، يعرض تطبيق جهات الاتصال شاشة تعديل. عندما يجرّب ينتهي التعديل ويحفظ التعديلات، سيعرض تطبيق جهات الاتصال قائمة جهات اتصال. عندما ينقر المستخدم على رجوع، يتم عرض تطبيقك.

إنشاء النية

لتعديل جهة اتصال، اتّصِل بـ Intent(action) من أجل إنشاء مقصد من خلال الإجراء ACTION_EDIT. اتصل بـ setDataAndType() لضبط قيمة البيانات لمحاولة العميل للتواصل على Contacts.CONTENT_LOOKUP_URI جهة الاتصال ونوع MIME على نوع Contacts.CONTENT_ITEM_TYPE MIME، لأنّ الاتصال بـ setType() يحلّ محلّ قيمة البيانات الحالية لمحاولة العميل للتواصل على Intent، عليك ضبط البيانات ونوع MIME في الوقت نفسه.

للحصول على رقم Contacts.CONTENT_LOOKUP_URI الخاص بجهة الاتصال، اتصل Contacts.getLookupUri(id, lookupkey) مع جهة الاتصال Contacts._ID و Contacts.LOOKUP_KEY كـ الوسيطة.

ملاحظة: قيمة LOOKUP_KEY لجهة الاتصال هي المعرّف الذي يجب استخدامه لاسترداد جهة اتصال. ويظلّ هذا المعرّف ثابتًا، حتى إذا غيّر مقدّم الخدمة معرّف صف جهة الاتصال لمعالجة العمليات الداخلية.

يوضّح لك المقتطف التالي كيفية إنشاء نية:

Kotlin

    // 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)
    }

Java

    // 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 (الإصدار 14 من واجهة برمجة التطبيقات) والإصدارات الأحدث، تؤدي مشكلة في تطبيق جهات الاتصال إلى حدوث خطأ التنقل. عندما يرسل تطبيقك طلب تعديل إلى تطبيق جهات الاتصال، ويُعدِّل المستخدمون جهة اتصال ويحفظونها، تظهر لهم شاشة قائمة جهات الاتصال عند النقر على رجوع. للرجوع إلى تطبيقك، سيضطر إلى النقر على التطبيقات الأخيرة واختيار تطبيقك.

للتغلب على هذه المشكلة في Android 4.0.3 (واجهة برمجة التطبيقات الإصدار 15) والإصدارات الأحدث، أضف مفتاح البيانات finishActivityOnSaveCompleted إلى الغرض، بقيمة true. وتقبل إصدارات Android التي تسبق الإصدار Android 4.0 هذا المفتاح، ولكن ليس له أي تأثير. لضبط البيانات الموسعة، قم بما يلي:

Kotlin

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

Java

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

إضافة بيانات موسّعة أخرى

لإضافة بيانات موسّعة إضافية إلى Intent، اتصل putExtra() حسب الحاجة. يمكنك إضافة بيانات موسّعة لحقول جهات الاتصال الشائعة باستخدام قيم المفاتيح المحدَّدة في Intents.Insert يُرجى العلم أنّه لا يمكن تعديل بعض الأعمدة في جدول ContactsContract.Contacts. يتم إدراج هذه الأعمدة في قسم الملخّص من مرجع واجهة برمجة التطبيقات للصف يليه ContactsContract.Contacts ضمن العنوان "تعديل".

إرسال الهدف

وأخيرًا، أرسل الهدف الذي أنشأته. مثلاً:

Kotlin

    // Sends the Intent
    startActivity(editIntent)

Java

    // Sends the Intent
    startActivity(editIntent);

السماح للمستخدمين باختيار إدراج المحتوى أو تعديله باستخدام نية

يمكنك السماح للمستخدمين باختيار ما إذا كانوا يريدون إدراج جهة اتصال أو تعديل جهة اتصال حالية من خلال إرسال Intent مع الإجراء ACTION_INSERT_OR_EDIT. على سبيل المثال، يمكن لتطبيق برنامج بريد إلكتروني السماح للمستخدمين بإضافة عنوان بريد إلكتروني وارد إلى جهة اتصال جديدة، أو إضافته كعنوان إضافي لجهة اتصال حالية. اضبط نوع MIME لهذا الطلب على Contacts.CONTENT_ITEM_TYPE، ولكن لا تضبط معرّف الموارد المنتظم (URI) للبيانات.

عند إرسال رسالة الغرض هذه، يعرض تطبيق جهات الاتصال قائمة بجهات الاتصال. يمكن للمستخدمين إدراج جهة اتصال جديدة أو اختيار جهة اتصال حالية وتعديلها. تتم تعبئة الشاشة التي تظهر إذا كانت أي حقول بيانات موسّعة تضيفها إلى الغرض. يمكنك استخدام أيّ من قيم المفاتيح المحدّدة في Intents.Insert. يوضّح المقتطف البرمجي التالي كيفية إنشاء النية وإرسالها:

Kotlin

    // 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)

Java

    // 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);