안드로이드
내용 제공자 사용하기, 연락처 조회
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를 실행하여 연락처 추가
앱을 실행하여 연락처 조회
반응형