안드로이드

내용 제공자 사용하기, 연락처 조회

liufeier 2021. 11. 1. 13:15
반응형

연락처에는 이름이나 전화번호와 같이 다양한 정보들이 있기 때문에 내용 제공자를 위한 코드가 더 많이 사용된다

 

연락처에 대한 정보는 ContactsContract.Contacts 객체가 가리키는 테이블에 저장되어 있다
연락처에 대한 상세 정보는 ContactsContract.Data 객체가 가리키는 테이블에 저장되어 있다

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.a64_sample_contacts">

    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.A64_Sample_Contacts">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

 

build.gradle(Module)

dependencies {
	...
    implementation 'com.yanzhenjie:permission:2.0.3'
}

 

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="연락처 가져오기" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_blue_bright">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/textView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="20sp" />
        </LinearLayout>
    </ScrollView>
</LinearLayout>

 

 

 

package com.example.a64_sample_contacts;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.runtime.Permission;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AndPermission.with(this)
                .runtime()
                .permission(Permission.READ_CONTACTS, Permission.WRITE_CONTACTS)
                .onGranted(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> permissions) {
                        showToast("허용된 권한 갯수 : " + permissions.size());
                    }
                })
                .onDenied(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> permissions) {
                        showToast("거부된 권한 갯수 : " + permissions.size());
                    }
                })
                .start();


        textView = findViewById(R.id.textView);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                chooseContacts();
            }
        });


    }

    public void chooseContacts() {
//        연락처 화면을 띄우기 위한 인텐트 만들기
//        액션 정보로 ACTION_PICK 전달
//        ContactsContract.Contacts.CONTENT_URI는 연락처 정보를 조회하는데 사용되는 URI 값
        Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);

        startActivityForResult(contactPickerIntent, 101);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            if (requestCode == 101) {
                try {

//                    전달받은 인텐트 객체의 getData 메소드를 호출하면, 선택된 연락처 정보를 가리키는 URI 객체가 반환됨
                    Uri contactsUri = data.getData();

//                    getLastPathSegment 메소드를 호출하여, 선택한 연락처의 id 값 확인하기
//                    이렇게 id 값을 확인하는 이유는 선택한 연락처의 상세 정보가 다른 곳에 저장되어 있기 때문
                    String id = contactsUri.getLastPathSegment();

                    getContacts(id);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }


    public void getContacts(String id) {
        Cursor cursor = null;
        String name = "";

        try {

//            ContentResolver 객체의 query 메소드 호출
//            1번 파라미터로 ContactsContract.Data.CONTENT_URI 전달
//            이 URI 값은 chooseContacts 메소드에서 인텐트를 만들 때 넣어주었던 URI 값과 다르다
//            ContactsContract.Data.CONTENT_URI는 연락처의 상세 정보를 조회하는데 사용하는 URI이다
//            3번 파라미터는 id 칼럼의 이름과 함께 `= ?` 붙여서 전달
//            4번 파라미터는 테이블에 있는 칼럼들 중에서 id 칼럼의 이름은 ContactsContract.Data.CONTACT_ID("contact_id")
            cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, ContactsContract.Data.CONTACT_ID + "= ?", new String[]{id}, null);

            if (cursor.moveToFirst()) {
//                연락처의 이름 값 출력
                name = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
                println("Name : " + name);
            }

            
//            모든 칼럼의 이름과 값 출력
            String columns[] = cursor.getColumnNames();
            for (String column : columns) {
                int index = cursor.getColumnIndex(column);
                String columnOutput = ("#" + index + " -> [ " + column + "] " + cursor.getString(index));
                println(columnOutput);
            }

            cursor.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void println(String data) {
        textView.append(data + "\n");
    }


    public void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }


}

 

 

 

avd를 실행하여 연락처 추가

 

 

 

 

 

 

앱을 실행하여 연락처 조회

반응형