Inserting a contact / Android architecture

by brnzn » Thu, 01 Jan 2009 08:06:22 GMT

Sponsored Links
 I have a question on inserting a contact, but it's the general
principle I'm most interested in.  I'd really love to hear from one of
the Android Engineers on this, because currently I find some of the
design decisions in Android perplexing, and I'd like to understand why
it is as it is.

The most direct way to insert a contact seems to be to use
Contacts.People.createPersonInMyContactsGroup(...).  Something like

        ContentValues values = new ContentValues();
        values.put(People.NAME, "Bernie");


We're constructing the person entity as a map.  This brings up a few
potential problems:
1. How do we know what the keys should be?  By convention Android's
own classes (such as People) declare static constants to tell us what
those keys should be, but this is only a convention.
2. How do we know what datatype is appropriate for a given key?
There's nothing to stop you or warn you when you push the wrong type
of data in.
3. How do we know what combination of keys is valid?  If a given
entity has mandatory properties, there's nothing to stop you or warn
you if you forget to set some of those mandatory properties.
4. We're potentially allocating two objects for every value - one for
the value itself and one for the key.  Where we use static constants,
this is less of an issue.

Why does the API not provide a Person object that we can populate and
then pass in to be persisted?  Perhaps something like this:

        Person p = new Person("Bernie");
        p.addGroupMembership("My Contacts");

        getContentResolver().insert(Person.CONTENT_URI, p);

The Person class tells clearly us:
1. What values can be set (by the existence of bean properties)
2. What datatype each property is
3. What values are are mandatory (probably by virtue of them being
required in constructor calls)

Is it a classloading issue?  I'm guessing no because we could easily
overcome that by making Person Serializable or Parcelable, splitting
it out into a JAR to be linked into whatever app needs it.

So what then is the philosophy that has driven the architecture to be
this way?



Inserting a contact / Android architecture

by Mark Murphy » Thu, 01 Jan 2009 08:45:44 GMT


I can't speak for the core Android team, so I cannot say specifically
why they made the design decision.

However, given their repeated insistence that they will not break binary
interfaces with Android OS updates, my guess is that's at least part of
their rationale. The definition of a "contact" has potential to change
significantly. They may feel that a more generic interface will help
them expand the scope of contacts without changing existing uses of the API.

To draw an analogy, it's a variant on the strong-vs.-weak typing
argument you see when Rubyists and Javanauts square off. Strong typing
has definite benefits, in terms of compile-time validations and
potential for optimization. However, strong typing can also "get in the
way", which is why some folk prefer weakly-typed or type-inferred languages.

Anyway, that's my guess. Take it with a grain of salt. Preferably a
large grain of salt, maybe one cubic foot or so... ;-)

Mark Murphy (a Commons Guy) 
_The Busy Coder's Guide to Android Development_ Version 1.9 Published!


Sponsored Links

Other Threads

1. Using KSoap2 with VB.Net webservice

Hello All,
I am having some serious difficulty using KSoap2 to connect to a
VB.Net webservice and am hoping I could get some help from someone who
is smarter than me. I have been trying to work this out for 2 weeks
with no luck.

So this is my problem. Using KSoap2 on the Android platform I have
successfully queried a super simple web service that I created using (It can be found at
I receive a XML result which looks quite reasonable to me.

ReturnCustomerObject2Result=anyType{CustomerID=1; FirstName=This is a
test; };

However at the point where I try to cast the object I am returning
from the webservice into a KvmSerializable object (as required by
KSoap2) I receive a java.lang.ClassCastException.

This is my object (I have excluded imports for brevity):

public class Customer extends BaseObject {

        private int m_CustomerID;
        private String m_FirstName;
        public static Class<? extends Customer> Customer_CLASS = new Customer

        public void setCustomerID(int CustomerID) {
                m_CustomerID = CustomerID;
        public int getCustomerID() {
                return m_CustomerID;
        public void setFirstName(String FirstName) {
                m_FirstName = FirstName;
        public String getFirstName() {
                return m_FirstName;

    public void getPropertyInfo(int index, Hashtable properties,
PropertyInfo info) {
        switch (index)
        case 0:
            info.type = PropertyInfo.INTEGER_CLASS;
   = "CustomerID";
        case 1:
            info.type = PropertyInfo.STRING_CLASS;
   = "FirstName";


        public Object getProperty(int index)
                switch (index) {
        case 0:
            return m_CustomerID;
        case 1:
            return m_FirstName;
            return null;

    public int getPropertyCount() {
        return 2;

        public void setProperty(int index, Object value) {

                switch (index) {
        case 0:
            m_CustomerID = Integer.parseInt(value.toString());
        case 1:
                 m_FirstName = value.toString();


private static final String SOAP_ACTION = "
private static final String METHOD_NAME = "ReturnCustomerObject2";
private static final String NAMESPACE = "";
private static final String URL = "http://";

public Boolean ExecuteSoapAction() {
        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope
        envelope.encodingStyle = SoapSerializationEnvelope.XSD;
"ReturnCustomerObject2", new Customer().getClass());

        envelope.dotNet = true;

        Customer Cust = new Customer();

        HttpTransportSE HttpTransport = new HttpTransportSE(URL);
        HttpTransport.debug = true;
        try {
      , envelope);
                Cust = (Customer) envelope.getResponse();
        catch (Exception ex) {
        return false;


2. Zeroconf AP

Hi Group,

I am surprised to see that the Android doesn't yet have a zeroconf
stack as part of its API. Zeroconf allows you to find services (eg Web
Servers, Instant Messaging peers, SIP) on a given network with minimal
effort, something a mobile device going to new places I would envisage
doing alot.

Obvious starting points could be Avahi (as found in most major linux
distributions and jmdns). Apple also have the open source
mDNSResponder. (zeroconf is found on the iPhone under the name

For more information see:


3. How can I call methods in Activity from an event listener of a custom Adapter?

4. device to device broadcasts possible via wi-fi?


6. question about orientation sensor

7. is an AppWidget Configuration Activity required?