2

In my PhoneGap app, I am trying to get the native Android contact picker to launch so I can fetch some phone numbers.

I researched online and couldn't find much until I saw the ContactView plugin: https://github.com/phonegap/phonegap-plugins/tree/master/Android/ContactView

When I set up the plugin according to the instructions, I encountered errors everywhere in its ContactView.java file. It seems that it is using a very old version of the plugin structure with ctx and other deprecated commands (e.g. startActivityForResult).

So I tried to convert it into a modern plugin by going through it line by line but I was too n00b and got stuck at about line 40 (inside the startContactActivity function). This is what I have so far:

package com.rearden;

import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.util.Log;

public class ContactView extends CordovaPlugin {
    private static final String TAG = "PickContactPlugin";
    private static final int PICK_CONTACT = 1;

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        Log.d(TAG, "Inside ContactView plugin.");

        JSONObject result = new JSONObject();

        if (action.equals("") || action.equals("ContactView")) {
            return startContactActivity();
        } else {
            Log.e(TAG, "Unknown action provided.");
            result.put("error", "Unknown action provided.");
            callbackContext.success(result);
            return false;
        }
    }

    public boolean startContactActivity() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
        //STUCK HERE
        this.cordova.getActivity().startActivityForResult((Plugin) this, intent, PICK_CONTACT);
    }

    @Override
    public void onActivityResult(int reqCode, int resultCode, Intent data) {
        String name = null;
        String number = null;
        String email = null;
        ContentResolver contentResolver = cordova.getActivity().getContentResolver();
        switch (reqCode) {
        case (PICK_CONTACT):
            if (resultCode == Activity.RESULT_OK) {
                Uri contactData = data.getData();
                Cursor c = contentResolver.query(contactData, null, null, null, null);
                if (c.moveToFirst()) {
                    String ContactID = c.getString(c
                            .getColumnIndex(ContactsContract.Contacts._ID));
                    String hasPhone = c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

                    if (Integer.parseInt(hasPhone) == 1) {
                        Cursor phoneCursor = contentResolver.query(
                                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                        null,
                                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                                + "='" + ContactID + "'", null,
                                        null);
                        while (phoneCursor.moveToNext()) {
                            number = phoneCursor
                                    .getString(phoneCursor
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        }
                    }
                    // get email address
                    Cursor emailCur = contentResolver.query( 
                            ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
                            null,
                            ContactsContract.CommonDataKinds.Email.CONTACT_ID + "='" + ContactID + "'", null,null); 
                        while (emailCur.moveToNext()) { 
                            // This would allow you get several email addresses
                                // if the email addresses were stored in an array
                            email = emailCur.getString(
                                          emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                            //String emailType = emailCur.getString(
                              //            emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE)); 
                        } 
                        emailCur.close();

                    name = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
                    JSONObject contactObject = new JSONObject();
                    try {
                        contactObject.put("name", name);
                        contactObject.put("phone", number);
                        contactObject.put("email", email);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                    this.success(new PluginResult(PluginResult.Status.OK,
                            contactObject), this.callback);
                }
            }
            break;
        }
    }
}

What I don't seem to be able to do is to find an equivalent for the "this.ctx.startActivityForResult" function.

I've already spent an entire day on this and it's starting to seem excessive, so I turn to you guys for help. Can it really be that hard to access the native contact picker?

adrianmcli
  • 1,956
  • 3
  • 21
  • 49
  • Hello, I found the same plugin and I managed to get it to work with phonegap 2.7.0. Did you mamage to fix yours? I am now trying to convert it to phonegap3.0 and its giving me a good kicking, see the question here http://stackoverflow.com/questions/18860177/phonegap-3-0-custom-plugin. Maybe something in there can help you if you haven't sorted it out already – Obi Sep 17 '13 at 21:37

2 Answers2

1

The equivalent is this.ctx.getActivity().getContentResolver().query

The code below works in cordova 2.6.

package com.rearden;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;

import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.apache.cordova.api.PluginResult.Status;

import android.util.Log;

public class ContactViewPlugin extends Plugin {
    private static final int PICK_CONTACT = 1;
    private String callback;

    @Override
    public PluginResult execute(String action, JSONArray args, String callbackId) {

        startContactActivity();
        PluginResult mPlugin = new PluginResult(PluginResult.Status.NO_RESULT);
        mPlugin.setKeepCallback(true);
        this.callback = callbackId;
        return mPlugin;
    }

    public void startContactActivity() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
        this.ctx.startActivityForResult((Plugin) this, intent, PICK_CONTACT);
    }

    @Override
    public void onActivityResult(int reqCode, int resultCode, Intent data) {
        String name = null;
        String number = null;
        String email = null;

        switch (reqCode) {
        case (PICK_CONTACT):
            if (resultCode == Activity.RESULT_OK) {

                Uri contactData = data.getData();
                Cursor c = this.ctx.getActivity().getContentResolver().query(contactData, null, null, null, null);
                if (c.moveToFirst()) {

                    String ContactID = c.getString(c
                            .getColumnIndex(ContactsContract.Contacts._ID));
                    String hasPhone = c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

                    if (Integer.parseInt(hasPhone) == 1) {

                        Cursor phoneCursor = this.ctx.getActivity().getContentResolver().query(
                                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                        null,
                                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                                + "='" + ContactID + "'", null,
                                        null);
                        while (phoneCursor.moveToNext()) {
                            number = phoneCursor
                                    .getString(phoneCursor
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        }
                    }

                    // get email address
                    Cursor emailCur = this.ctx.getActivity().getContentResolver().query( 
                            ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
                            null,
                            ContactsContract.CommonDataKinds.Email.CONTACT_ID + "='" + ContactID + "'", null,null); 
                        while (emailCur.moveToNext()) { 
                            // This would allow you get several email addresses
                                // if the email addresses were stored in an array
                            email = emailCur.getString(
                                          emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                            //String emailType = emailCur.getString(
                              //            emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE)); 
                        } 
                        emailCur.close();

                    name = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
                    JSONObject contactObject = new JSONObject();
                    try {
                        contactObject.put("name", name);
                        contactObject.put("phone", number);
                        contactObject.put("email", email);

                    } catch (JSONException e) {

                        e.printStackTrace();
                    }

                    this.success(new PluginResult(PluginResult.Status.OK,
                            contactObject), this.callback);
                }
            }
            break;
        }
    }
}

I also changed the JS file.

var ContactViewPlugin = function() {
};

ContactViewPlugin.prototype.show = function(successCallback, failureCallback) {

  console.log('calling *** show');

    return cordova.exec(successCallback,    
            failureCallback,
            'ContactViewPlugin',
            'show',
            []); 

};


if(!window.plugins) { 
  window.plugins = {};
}
if (!window.plugins.contactViewPlugin) {
  window.plugins.contactViewPlugin = new ContactViewPlugin();
}

Do not forget to add the plugin to the config.xml list.

ppcano
  • 2,831
  • 1
  • 24
  • 19
  • can i find any example where i can see all the code i am new to phonegap and i want to do exactly same thing – Uahmed Jul 14 '13 at 14:34
0

in cordova 3.0.0 this worked for me

this.cordova.startActivityForResult((CordovaPlugin) this, intent, PICK_CONTACT);
enRaiser
  • 2,606
  • 2
  • 21
  • 39