Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# react-native-contacts-wrapper

> This project is just a fork of https://github.com/LynxITDigital/react-native-contacts-wrapper with https://github.com/LynxITDigital/react-native-contacts-wrapper/pull/27
> Please refer to original project for issues/etc.

![alt tag](https://github.com/LynxITDigital/Screenshots/blob/master/RN%20Contacts%20Wrapper%20example.gif)

This is a simple wrapper for the native iOS and Android Contact Picker UIs. When calling the API functions, the appropriate picker is launched. If a contact is picked, the promise is resolved with the requested data about the picked contact.
This is a simple wrapper for the native iOS and Android Contact Picker UIs. When calling the API functions, the appropriate picker is launched. If a contact is picked, the promise is resolved with the requested data about the picked contact.

This uses the ContactsContract API for Android, AddressBook library for iOS8 and below and the new Contacts library for ios9+.

The API is currently very basic. This was started just as a way of selecting a contact's email address. The getContact function was added as a more generic way of returning contact data. Currently this returns Name, Phone and Email for picked contact. In future more fields will be added to this, and possibly more specific methods similar to getEmail.
The API is currently very basic. This was started just as a way of selecting a contact's email address. The getContact function was added as a more generic way of returning contact data. Currently this returns Name, Phone and Email for picked contact. In future more fields will be added to this, and possibly more specific methods similar to getEmail.

Feel free to extend the functionality so it's more useful for everyone - all PRs welcome!

Expand All @@ -18,12 +21,13 @@ If you have rnpm installed, all you need to do is

```
npm install react-native-contacts-wrapper --save
rnpm link react-native-contacts-wrapper
react-native link react-native-contacts-wrapper
```

### Manual

#### Android (with RN 0.29 and above)

in `settings.gradle`

```
Expand Down Expand Up @@ -57,19 +61,18 @@ protected List<ReactPackage> getPackages() {

in `AndroidManifest.xml`
make sure you have the following setting even if you have done `react-native upgrade`

```
<application
android:name=".MainApplication"

```

Also add
Also add

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


#### iOS

1. Open your xCode project
Expand All @@ -83,13 +86,11 @@ Also add
9. In same screen, click + again, you should now see the .a file for you project, Add this
10. Clean and Rebuild your Xcode project


##API

`getContact` (Promise) - returns basic contact data as a JS object. Currently returns name, first phone number and first email for contact.
`getContact` (Promise) - returns basic contact data as a JS object. Currently returns name, first phone number and first email for contact.
`getEmail` (Promise) - returns first email address (if found) for contact as string.


##Usage

Methods should be called from React Native as any other promise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.uimanager.ViewManager;

public class ContactsWrapper extends ReactContextBaseJavaModule implements ActivityEventListener {
Expand Down Expand Up @@ -58,12 +59,15 @@ public class ContactsWrapper extends ReactContextBaseJavaModule implements Activ
add(ContactsContract.CommonDataKinds.Email.TYPE);
add(ContactsContract.CommonDataKinds.Email.LABEL);
}};
private Context context;


public ContactsWrapper(ReactApplicationContext reactContext) {
super(reactContext);
this.contentResolver = getReactApplicationContext().getContentResolver();
reactContext.addActivityEventListener(this);
this.context = reactContext;

}

@Override
Expand Down Expand Up @@ -109,8 +113,8 @@ private void launchPicker(Promise contactsPromise, int requestCode) {
public void onActivityResult(Activity ContactsWrapper, final int requestCode, final int resultCode, final Intent intent) {

if(mContactsPromise == null || mCtx == null
|| (requestCode != CONTACT_REQUEST && requestCode != EMAIL_REQUEST)){
return;
|| (requestCode != CONTACT_REQUEST && requestCode != EMAIL_REQUEST)){
return;
}

String email = null;
Expand All @@ -125,7 +129,12 @@ public void onActivityResult(Activity ContactsWrapper, final int requestCode, fi
//First get ID
String id = null;
int idx;

WritableMap contactData = Arguments.createMap();
WritableArray phonesArray = Arguments.createArray();
WritableArray emailsArray = Arguments.createArray();


Cursor cursor = this.contentResolver.query(contactUri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
idx = cursor.getColumnIndex(ContactsContract.Contacts._ID);
Expand All @@ -143,8 +152,8 @@ public void onActivityResult(Activity ContactsWrapper, final int requestCode, fi

// Create the projection (SQL fields) and sort order.
String[] projection = {
ContactsContract.Contacts.Entity.MIMETYPE,
ContactsContract.Contacts.Entity.DATA1
ContactsContract.Contacts.Entity.MIMETYPE,
ContactsContract.Contacts.Entity.DATA1
};
String sortOrder = ContactsContract.Contacts.Entity.RAW_CONTACT_ID + " ASC";
cursor = this.contentResolver.query(contactUri, projection, null, null, sortOrder);
Expand All @@ -155,9 +164,71 @@ public void onActivityResult(Activity ContactsWrapper, final int requestCode, fi
/* Map Any contact data we want returned to the JS object key for React Native */
HashMap<String, String> returnKeys = new HashMap<String, String>();
returnKeys.put(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE, "name");
returnKeys.put(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, "phone");
returnKeys.put(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE, "email");

// loops through all phones

Cursor phones = this.contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id, null, null);
while (phones.moveToNext())
{
WritableMap phoneObj = Arguments.createMap();
String number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
int type = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
String phoneType = "";
switch (type) {
case ContactsContract.CommonDataKinds.Phone.TYPE_HOME:
// do something with the Home number here..
phoneType = " home";
break;
case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
// do something with the Mobile number here...
phoneType = "mobile";
break;
case ContactsContract.CommonDataKinds.Phone.TYPE_WORK:
phoneType = "work";
// do something with the Work number here...
break;
}
phoneObj.putString("number", number);
phoneObj.putString("number_type", phoneType);
phonesArray.pushMap(phoneObj);
}
phones.close();

// loops through all emails
Cursor emails = this.contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + id, null, null);
while (emails.moveToNext())
{
WritableMap emailObj = Arguments.createMap();
String emailAddress = emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));
int type = emails.getInt(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
String emailType = "";
switch (type) {
case ContactsContract.CommonDataKinds.Email.TYPE_HOME:
// do something with the Home number here..
emailType = "home";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_MOBILE:
// do something with the Mobile number here...
emailType = "mobile";
break;
case ContactsContract.CommonDataKinds.Email.TYPE_WORK:
emailType = "work";
// do something with the Work number here...
break;
}
Log.w(">>>>>>>>>>>>>>>>>>>>>>>>>>>>", emailType);
emailObj.putString("address", emailAddress);
emailObj.putString("address_type", emailType);
emailsArray.pushMap(emailObj);
}
emails.close();

contactData.putArray("emails", emailsArray);
contactData.putArray("phones", phonesArray);

// this now only grabs the name of the contact
int dataIdx = cursor.getColumnIndex(ContactsContract.Contacts.Entity.DATA1);
int mimeIdx = cursor.getColumnIndex(ContactsContract.Contacts.Entity.MIMETYPE);
if (cursor.moveToFirst()) {
Expand All @@ -172,6 +243,7 @@ public void onActivityResult(Activity ContactsWrapper, final int requestCode, fi

cursor.close();
if(foundData) {
// send contact back
mContactsPromise.resolve(contactData);
return;
} else {
Expand All @@ -193,8 +265,8 @@ public void onActivityResult(Activity ContactsWrapper, final int requestCode, fi

// query for everything email
Cursor cursor = mCtx.getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=?", new String[]{id},
null);
null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=?", new String[]{id},
null);

int emailIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);

Expand Down
Loading