Skip to content

Instantly share code, notes, and snippets.

@reuniware
Created October 8, 2019 15:42
Show Gist options
  • Save reuniware/9818195a13de752e3f5c59d915135892 to your computer and use it in GitHub Desktop.
Save reuniware/9818195a13de752e3f5c59d915135892 to your computer and use it in GitHub Desktop.
Access contacts with Kotlin on Android
//https://medium.com/@manuaravindpta/fetching-contacts-from-device-using-kotlin-6c6d3e76574f
package com.dev2qa.example.datasharing.contacts;
import android.Manifest;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.dev2qa.example.R;
import com.dev2qa.example.datasharing.contacts.dto.ContactDTO;
import com.dev2qa.example.datasharing.contacts.dto.DataDTO;
import java.util.ArrayList;
import java.util.List;
public class ContactsOperationActivity extends AppCompatActivity {
private static final String TAG_ANDROID_CONTACTS = "ANDROID_CONTACTS";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts_operation);
setTitle("dev2qa.com - Android Contacts Operate Example.");
// Load all contacts, and print each contact as log debug info.
Button loadButton = (Button)findViewById(R.id.contact_operate_load);
loadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(!hasPhoneContactsPermission(Manifest.permission.READ_CONTACTS))
{
requestPermission(Manifest.permission.READ_CONTACTS);
}else {
getAllContacts();
Toast.makeText(ContactsOperationActivity.this, "Contact data has been printed in the android monitor log..", Toast.LENGTH_SHORT).show();
}
}
});
}
/* Return all contacts and show each contact data in android monitor console as debug info. */
private List<ContactDTO> getAllContacts()
{
List<ContactDTO> ret = new ArrayList<ContactDTO>();
// Get all raw contacts id list.
List<Integer> rawContactsIdList = getRawContactsIdList();
int contactListSize = rawContactsIdList.size();
ContentResolver contentResolver = getContentResolver();
// Loop in the raw contacts list.
for(int i=0;i<contactListSize;i++)
{
// Get the raw contact id.
Integer rawContactId = rawContactsIdList.get(i);
Log.d(TAG_ANDROID_CONTACTS, "raw contact id : " + rawContactId.intValue());
// Data content uri (access data table. )
Uri dataContentUri = ContactsContract.Data.CONTENT_URI;
// Build query columns name array.
List<String> queryColumnList = new ArrayList<String>();
// ContactsContract.Data.CONTACT_ID = "contact_id";
queryColumnList.add(ContactsContract.Data.CONTACT_ID);
// ContactsContract.Data.MIMETYPE = "mimetype";
queryColumnList.add(ContactsContract.Data.MIMETYPE);
queryColumnList.add(ContactsContract.Data.DATA1);
queryColumnList.add(ContactsContract.Data.DATA2);
queryColumnList.add(ContactsContract.Data.DATA3);
queryColumnList.add(ContactsContract.Data.DATA4);
queryColumnList.add(ContactsContract.Data.DATA5);
queryColumnList.add(ContactsContract.Data.DATA6);
queryColumnList.add(ContactsContract.Data.DATA7);
queryColumnList.add(ContactsContract.Data.DATA8);
queryColumnList.add(ContactsContract.Data.DATA9);
queryColumnList.add(ContactsContract.Data.DATA10);
queryColumnList.add(ContactsContract.Data.DATA11);
queryColumnList.add(ContactsContract.Data.DATA12);
queryColumnList.add(ContactsContract.Data.DATA13);
queryColumnList.add(ContactsContract.Data.DATA14);
queryColumnList.add(ContactsContract.Data.DATA15);
// Translate column name list to array.
String queryColumnArr[] = queryColumnList.toArray(new String[queryColumnList.size()]);
// Build query condition string. Query rows by contact id.
StringBuffer whereClauseBuf = new StringBuffer();
whereClauseBuf.append(ContactsContract.Data.RAW_CONTACT_ID);
whereClauseBuf.append("=");
whereClauseBuf.append(rawContactId);
// Query data table and return related contact data.
Cursor cursor = contentResolver.query(dataContentUri, queryColumnArr, whereClauseBuf.toString(), null, null);
/* If this cursor return database table row data.
If do not check cursor.getCount() then it will throw error
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0.
*/
if(cursor!=null && cursor.getCount() > 0)
{
StringBuffer lineBuf = new StringBuffer();
cursor.moveToFirst();
lineBuf.append("Raw Contact Id : ");
lineBuf.append(rawContactId);
long contactId = cursor.getLong(cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID));
lineBuf.append(" , Contact Id : ");
lineBuf.append(contactId);
do{
// First get mimetype column value.
String mimeType = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
lineBuf.append(" \r\n , MimeType : ");
lineBuf.append(mimeType);
List<String> dataValueList = getColumnValueByMimetype(cursor, mimeType);
int dataValueListSize = dataValueList.size();
for(int j=0;j < dataValueListSize;j++)
{
String dataValue = dataValueList.get(j);
lineBuf.append(" , ");
lineBuf.append(dataValue);
}
}while(cursor.moveToNext());
Log.d(TAG_ANDROID_CONTACTS, lineBuf.toString());
}
Log.d(TAG_ANDROID_CONTACTS, "=========================================================================");
}
return ret;
}
/*
* Get email type related string format value.
* */
private String getEmailTypeString(int dataType)
{
String ret = "";
if(ContactsContract.CommonDataKinds.Email.TYPE_HOME == dataType)
{
ret = "Home";
}else if(ContactsContract.CommonDataKinds.Email.TYPE_WORK==dataType)
{
ret = "Work";
}
return ret;
}
/*
* Get phone type related string format value.
* */
private String getPhoneTypeString(int dataType)
{
String ret = "";
if(ContactsContract.CommonDataKinds.Phone.TYPE_HOME == dataType)
{
ret = "Home";
}else if(ContactsContract.CommonDataKinds.Phone.TYPE_WORK==dataType)
{
ret = "Work";
}else if(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE==dataType)
{
ret = "Mobile";
}
return ret;
}
/*
* Return data column value by mimetype column value.
* Because for each mimetype there has not only one related value,
* such as Organization.CONTENT_ITEM_TYPE need return company, department, title, job description etc.
* So the return is a list string, each string for one column value.
* */
private List<String> getColumnValueByMimetype(Cursor cursor, String mimeType)
{
List<String> ret = new ArrayList<String>();
switch (mimeType)
{
// Get email data.
case ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE :
// Email.ADDRESS == data1
String emailAddress = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));
// Email.TYPE == data2
int emailType = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
String emailTypeStr = getEmailTypeString(emailType);
ret.add("Email Address : " + emailAddress);
ret.add("Email Int Type : " + emailType);
ret.add("Email String Type : " + emailTypeStr);
break;
// Get im data.
case ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE:
// Im.PROTOCOL == data5
String imProtocol = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.PROTOCOL));
// Im.DATA == data1
String imId = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA));
ret.add("IM Protocol : " + imProtocol);
ret.add("IM ID : " + imId);
break;
// Get nickname
case ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE:
// Nickname.NAME == data1
String nickName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Nickname.NAME));
ret.add("Nick name : " + nickName);
break;
// Get organization data.
case ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE:
// Organization.COMPANY == data1
String company = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.COMPANY));
// Organization.DEPARTMENT == data5
String department = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.DEPARTMENT));
// Organization.TITLE == data4
String title = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE));
// Organization.JOB_DESCRIPTION == data6
String jobDescription = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.JOB_DESCRIPTION));
// Organization.OFFICE_LOCATION == data9
String officeLocation = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.OFFICE_LOCATION));
ret.add("Company : " + company);
ret.add("department : " + department);
ret.add("Title : " + title);
ret.add("Job Description : " + jobDescription);
ret.add("Office Location : " + officeLocation);
break;
// Get phone number.
case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE:
// Phone.NUMBER == data1
String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// Phone.TYPE == data2
int phoneTypeInt = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
String phoneTypeStr = getPhoneTypeString(phoneTypeInt);
ret.add("Phone Number : " + phoneNumber);
ret.add("Phone Type Integer : " + phoneTypeInt);
ret.add("Phone Type String : " + phoneTypeStr);
break;
// Get sip address.
case ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE:
// SipAddress.SIP_ADDRESS == data1
String address = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS));
// SipAddress.TYPE == data2
int addressTypeInt = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.TYPE));
String addressTypeStr = getEmailTypeString(addressTypeInt);
ret.add("Address : " + address);
ret.add("Address Type Integer : " + addressTypeInt);
ret.add("Address Type String : " + addressTypeStr);
break;
// Get display name.
case ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE:
// StructuredName.DISPLAY_NAME == data1
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
// StructuredName.GIVEN_NAME == data2
String givenName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
// StructuredName.FAMILY_NAME == data3
String familyName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
ret.add("Display Name : " + displayName);
ret.add("Given Name : " + givenName);
ret.add("Family Name : " + familyName);
break;
// Get postal address.
case ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE:
// StructuredPostal.COUNTRY == data10
String country = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));
// StructuredPostal.CITY == data7
String city = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
// StructuredPostal.REGION == data8
String region = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
// StructuredPostal.STREET == data4
String street = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
// StructuredPostal.POSTCODE == data9
String postcode = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));
// StructuredPostal.TYPE == data2
int postType = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE));
String postTypeStr = getEmailTypeString(postType);
ret.add("Country : " + country);
ret.add("City : " + city);
ret.add("Region : " + region);
ret.add("Street : " + street);
ret.add("Postcode : " + postcode);
ret.add("Post Type Integer : " + postType);
ret.add("Post Type String : " + postTypeStr);
break;
// Get identity.
case ContactsContract.CommonDataKinds.Identity.CONTENT_ITEM_TYPE:
// Identity.IDENTITY == data1
String identity = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Identity.IDENTITY));
// Identity.NAMESPACE == data2
String namespace = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Identity.NAMESPACE));
ret.add("Identity : " + identity);
ret.add("Identity Namespace : " + namespace);
break;
// Get photo.
case ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE:
// Photo.PHOTO == data15
String photo = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO));
// Photo.PHOTO_FILE_ID == data14
String photoFileId = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO_FILE_ID));
ret.add("Photo : " + photo);
ret.add("Photo File Id: " + photoFileId);
break;
// Get group membership.
case ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE:
// GroupMembership.GROUP_ROW_ID == data1
int groupId = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID));
ret.add("Group ID : " + groupId);
break;
// Get website.
case ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE:
// Website.URL == data1
String websiteUrl = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Website.URL));
// Website.TYPE == data2
int websiteTypeInt = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Website.TYPE));
String websiteTypeStr = getEmailTypeString(websiteTypeInt);
ret.add("Website Url : " + websiteUrl);
ret.add("Website Type Integer : " + websiteTypeInt);
ret.add("Website Type String : " + websiteTypeStr);
break;
// Get note.
case ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE:
// Note.NOTE == data1
String note = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Note.NOTE));
ret.add("Note : " + note);
break;
}
return ret;
}
// Return all raw_contacts _id in a list.
private List<Integer> getRawContactsIdList()
{
List<Integer> ret = new ArrayList<Integer>();
ContentResolver contentResolver = getContentResolver();
// Row contacts content uri( access raw_contacts table. ).
Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI;
// Return _id column in contacts raw_contacts table.
String queryColumnArr[] = {ContactsContract.RawContacts._ID};
// Query raw_contacts table and return raw_contacts table _id.
Cursor cursor = contentResolver.query(rawContactUri,queryColumnArr, null, null, null);
if(cursor!=null)
{
cursor.moveToFirst();
do{
int idColumnIndex = cursor.getColumnIndex(ContactsContract.RawContacts._ID);
int rawContactsId = cursor.getInt(idColumnIndex);
ret.add(new Integer(rawContactsId));
}while(cursor.moveToNext());
}
cursor.close();
return ret;
}
// Check whether user has phone contacts manipulation permission or not.
private boolean hasPhoneContactsPermission(String permission)
{
boolean ret = false;
// If android sdk version is bigger than 23 the need to check run time permission.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// return phone read contacts permission grant status.
int hasPermission = ContextCompat.checkSelfPermission(getApplicationContext(), permission);
// If permission is granted then return true.
if (hasPermission == PackageManager.PERMISSION_GRANTED) {
ret = true;
}
}else
{
ret = true;
}
return ret;
}
// Request a runtime permission to app user.
private void requestPermission(String permission)
{
String requestPermissionArray[] = {permission};
ActivityCompat.requestPermissions(this, requestPermissionArray, 1);
}
// After user select Allow or Deny button in request runtime permission dialog
// , this method will be invoked.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
int length = grantResults.length;
if(length > 0)
{
int grantResult = grantResults[0];
if(grantResult == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "You allowed permission, please click the button again.", Toast.LENGTH_LONG).show();
}else
{
Toast.makeText(getApplicationContext(), "You denied permission.", Toast.LENGTH_LONG).show();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment