인텐트를 사용하여 연락처 수정

이 과정에서는 Intent를 사용하여 새 연락처를 삽입하거나 연락처 데이터를 수정하는 방법을 설명합니다. 연락처 제공자에게 직접 액세스하는 대신 Intent가 적절한 Activity를 실행하는 연락처 앱을 시작합니다. 이 과정에서 설명하는 수정 작업을 하기 위해 Intent에 있는 확장된 데이터를 전송하면 실행된 Activity의 UI에 데이터가 입력됩니다.

다음과 같은 이유로 연락처 제공자를 수정할 때 Intent를 사용하여 단일 연락처를 삽입하거나 업데이트하는 것이 좋습니다.

  • 고유 UI 및 코드를 개발하는 데 소요되는 시간과 노력을 절약할 수 있습니다.
  • 연락처 제공자의 규칙을 따르지 않는 수정사항으로 인한 오류가 발생하지 않도록 합니다.
  • 요청해야 하는 권한 수를 줄여줍니다. 이미 수정 권한이 있는 연락처 앱에 수정을 위임하므로 연락처 제공자에 기록할 수 있는 권한이 필요하지 않습니다.

인텐트를 사용하여 새 연락처 삽입

앱에서 새 데이터를 받으면 사용자가 새로운 연락처를 삽입하도록 허용하고 싶은 경우가 자주 있습니다. 예를 들어 음식점 리뷰 앱에서 사용자가 음식점의 리뷰를 작성하면서 특정 음식점을 연락처로 추가할 수 있도록 허용할 수 있습니다. 인텐트를 사용하여 이 작업을 하려면 사용할 수 있는 최대한 많은 데이터를 사용하여 인텐트를 만든 후 연락처 앱으로 전송합니다.

연락처 앱을 사용하여 연락처를 삽입하면 새로운 원시 연락처가 연락처 제공자의 ContactsContract.RawContacts 표에 삽입됩니다. 필요한 경우 연락처 앱에서 사용자에게 원시 연락처를 만들 때 사용할 계정 유형 및 계정을 요청하는 메시지를 표시합니다. 또한 연락처 앱은 사용자에게 원시 연락처가 이미 있는지 여부를 알립니다. 그러면 사용자는 삽입을 취소하도록 선택할 수 있으며 이 경우 연락처가 생성되지 않습니다. 원시 연락처에 관해 자세히 알아보려면 연락처 제공자 API 가이드를 참조하세요.

인텐트 만들기

시작하려면 새 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
    }
    

자바

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

자바

    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)
    

자바

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

호출하면 연락처 앱에 화면이 열리며 사용자가 새로운 연락처를 입력할 수 있도록 허용합니다. 연락처의 계정 유형 및 계정 이름은 화면 상단에 표시됩니다. 사용자가 데이터를 입력하고 완료를 클릭하면 연락처 앱의 연락처 목록이 표시됩니다. 사용자는 뒤로를 클릭하여 다시 앱으로 돌아옵니다.

인텐트를 사용하여 기존 연락처 수정

사용자가 이미 관심 있는 연락처를 선택한 경우 Intent를 사용하여 기존 연락처를 수정하는 것이 좋습니다. 예를 들어 앱이 주소는 있지만 우편번호는 없는 연락처를 찾으면 사용자에게 우편번호를 찾은 후 연락처에 추가할 수 있는 옵션을 제공합니다.

인텐트를 사용하여 기존 연락처를 수정하려면 연락처를 삽입하는 것과 비슷한 절차를 사용하세요. 인텐트를 사용하여 새 연락처 삽입 섹션에 설명된대로 인텐트를 만들고 연락처의 Contacts.CONTENT_LOOKUP_URI와 MIME 유형 Contacts.CONTENT_ITEM_TYPE을 인텐트에 추가하세요. 이미 갖고 있는 세부정보를 사용하여 연락처를 수정하려는 경우 인텐트의 확장 데이터에 넣을 수 있습니다. 일부 이름 열은 인텐트를 사용하여 수정할 수 없으며 이러한 열은 ContactsContract.Contacts 클래스의 API 참조 요약 섹션 내 '업데이트' 아래에 표시됩니다.

마지막으로 인텐트를 전송합니다. 연락처 앱에서 이에 대한 응답으로 수정 화면을 표시합니다. 사용자가 수정을 완료하고 수정 사항을 저장하면 연락처 앱에서 연락처 목록을 표시합니다. 사용자가 뒤로를 클릭하면 내 앱이 표시됩니다.

인텐트 만들기

연락처를 수정하려면 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._IDContacts.LOOKUP_KEY 값을 인수로 사용해야 합니다.

참고: 연락처를 검색할 때 연락처의 LOOKUP_KEY 값을 식별자로 사용해야 합니다. 이 값은 제공자가 내부 작업을 처리하기 위해 연락처의 행 ID를 변경해도 상수로 유지됩니다.

다음 스니펫은 인텐트를 만드는 방법을 보여줍니다.

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

자바

        // 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(API 버전 14) 이상에서 연락처 앱에 문제로 인해 탐색 오류가 발생합니다. 앱이 연락처 앱으로 수정 인텐트를 전송하고 사용자가 연락처를 수정한 후 저장한 다음 뒤로를 클릭하면 연락처 목록 화면이 표시됩니다. 앱으로 다시 돌아가려면 사용자가 최근을 클릭한 후 앱을 선택해야 합니다.

Android 4.0.3(API 버전 15) 이상에서 이 문제를 해결하려면 인텐트에 확장 데이터 키 finishActivityOnSaveCompleted를 추가하고 값을 true로 설정하세요. Android 4.0 이전 버전에서는 이 키를 사용할 수 있지만 영향을 미치지 않습니다. 확장 데이터를 설정하려면 다음과 같이 작업하세요.

Kotlin

        // 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 클래스의 API 참조 요약 섹션 내 '업데이트' 아래에 표시됩니다.

인텐트 전송

마지막으로, 구성한 인텐트를 전송합니다. 예를 들면 다음과 같습니다.

Kotlin

        // Sends the Intent
        startActivity(editIntent)
    

자바

        // Sends the Intent
        startActivity(editIntent);
    

사용자가 인텐트를 사용하여 삽입 또는 수정하도록 함

ACTION_INSERT_OR_EDIT 동작과 함께 Intent를 전송하여 사용자가 연락처를 삽입할지 수정할지 여부를 선택하도록 할 수 있습니다. 예를 들어 이메일 클라이언트 앱에서 사용자가 수신 이메일 주소를 새로운 연락처에 추가할지 아니면 기존 연락처에 추가적인 이메일 주소로 입력할 것인지 선택하도록 할 수 있습니다. 이 인텐트의 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)
    

자바

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