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

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

يُعدّ استخدام 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 جهة الاتصال ونوع 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 لجهة الاتصال هي المعرّف الذي يجب استخدامه لاسترداد جهة اتصال. ويظل ثابتًا، حتى إذا غيّر الموفّر رقم تعريف صف جهة الاتصال للتعامل مع العمليات الداخلية.

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

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

إضافة علامة التنقّل

في الإصدار 4.0 من Android (الإصدار 14 من واجهة برمجة التطبيقات) والإصدارات الأحدث، تحدث مشكلة في تطبيق جهات الاتصال تؤدي إلى التنقّل بشكل غير صحيح. عندما يرسل تطبيقك طلب تعديل إلى تطبيق جهات الاتصال، ويعدّل المستخدمون جهة اتصال ويحفظونها، تظهر لهم شاشة قائمة جهات الاتصال عند النقر على رجوع. للرجوع إلى تطبيقك، عليهم النقر على التطبيقات المستخدَمة مؤخرًا واختيار تطبيقك.

لحلّ هذه المشكلة في الإصدار 4.0.3 من نظام التشغيل Android (الإصدار 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);