com.phonegap.ContactAccessor.java Source code

Java tutorial

Introduction

Here is the source code for com.phonegap.ContactAccessor.java

Source

// Taken from Android Tutorials
/*
 * PhoneGap is available under *either* the terms of the modified BSD license *or* the
 * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
 * 
 * Copyright (c) 2005-2010, Nitobi Software Inc.
 * Copyright (c) 2010, IBM Corporation
 */
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.phonegap;

import java.lang.reflect.Constructor;
import java.util.HashMap;

import android.app.Activity;
import android.util.Log;
import android.webkit.WebView;

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

/**
 * This abstract class defines SDK-independent API for communication with
 * Contacts Provider. The actual implementation used by the application depends
 * on the level of API available on the device. If the API level is Cupcake or
 * Donut, we want to use the {@link ContactAccessorSdk3_4} class. If it is
 * Eclair or higher, we want to use {@link ContactAccessorSdk5}.
 */
public abstract class ContactAccessor {

    /**
     * Static singleton instance of {@link ContactAccessor} holding the
     * SDK-specific implementation of the class.
     */
    private static ContactAccessor sInstance;
    protected final String LOG_TAG = "ContactsAccessor";
    protected Activity mApp;
    protected WebView mView;

    public static ContactAccessor getInstance(WebView view, Activity app) {
        if (sInstance == null) {
            String className;

            /*
             * Check the version of the SDK we are running on. Choose an
             * implementation class designed for that version of the SDK.
             *
             * Unfortunately we have to use strings to represent the class
             * names. If we used the conventional ContactAccessorSdk5.class.getName()
             * syntax, we would get a ClassNotFoundException at runtime on pre-Eclair SDKs.
             * Using the above syntax would force Dalvik to load the class and try to
             * resolve references to all other classes it uses. Since the pre-Eclair
             * does not have those classes, the loading of ContactAccessorSdk5 would fail.
             */

            if (android.os.Build.VERSION.RELEASE.startsWith("1.")) {
                className = "com.phonegap.ContactAccessorSdk3_4";
            } else {
                className = "com.phonegap.ContactAccessorSdk5";
            }

            /*
             * Find the required class by name and instantiate it.
             */
            try {
                Class<? extends ContactAccessor> clazz = Class.forName(className).asSubclass(ContactAccessor.class);
                // Grab constructor for contactsmanager class dynamically.
                Constructor<? extends ContactAccessor> classConstructor = clazz.getConstructor(
                        Class.forName("android.webkit.WebView"), Class.forName("android.app.Activity"));
                sInstance = classConstructor.newInstance(view, app);
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        }

        return sInstance;
    }

    /**
     * Check to see if the data associated with the key is required to 
     * be populated in the Contact object.
     * @param key 
     * @param map created by running buildPopulationSet.
     * @return true if the key data is required
     */
    protected boolean isRequired(String key, HashMap<String, Boolean> map) {
        Boolean retVal = map.get(key);
        return (retVal == null) ? false : retVal.booleanValue();
    }

    /**
     * Create a hash map of what data needs to be populated in the Contact object
     * @param fields the list of fields to populate
     * @return the hash map of required data
     */
    protected HashMap<String, Boolean> buildPopulationSet(JSONArray fields) {
        HashMap<String, Boolean> map = new HashMap<String, Boolean>();

        String key;
        try {
            for (int i = 0; i < fields.length(); i++) {
                key = fields.getString(i);
                if (key.startsWith("displayName")) {
                    map.put("displayName", true);
                } else if (key.startsWith("name")) {
                    map.put("name", true);
                } else if (key.startsWith("nickname")) {
                    map.put("nickname", true);
                } else if (key.startsWith("phoneNumbers")) {
                    map.put("phoneNumbers", true);
                } else if (key.startsWith("emails")) {
                    map.put("emails", true);
                } else if (key.startsWith("addresses")) {
                    map.put("addresses", true);
                } else if (key.startsWith("ims")) {
                    map.put("ims", true);
                } else if (key.startsWith("organizations")) {
                    map.put("organizations", true);
                } else if (key.startsWith("birthday")) {
                    map.put("birthday", true);
                } else if (key.startsWith("anniversary")) {
                    map.put("anniversary", true);
                } else if (key.startsWith("note")) {
                    map.put("note", true);
                } else if (key.startsWith("relationships")) {
                    map.put("relationships", true);
                } else if (key.startsWith("urls")) {
                    map.put("urls", true);
                } else if (key.startsWith("photos")) {
                    map.put("photos", true);
                }
            }
        } catch (JSONException e) {
            Log.e(LOG_TAG, e.getMessage(), e);
        }
        return map;
    }

    /**
     * Convenience method to get a string from a JSON object.  Saves a 
     * lot of try/catch writing.
     * If the property is not found in the object null will be returned.
     * 
     * @param obj contact object to search
     * @param property to be looked up
     * @return The value of the property
     */
    protected String getJsonString(JSONObject obj, String property) {
        String value = null;
        try {
            value = obj.getString(property);
            if (value.equals("null")) {
                Log.d(LOG_TAG, property + " is string called 'null'");
                value = null;
            }
        } catch (JSONException e) {
            Log.d(LOG_TAG, "Could not get = " + e.getMessage());
        }
        return value;
    }

    /**
     * Handles adding a JSON Contact object into the database.
     * @return TODO
     */
    public abstract boolean save(JSONObject contact);

    /**
     * Handles searching through SDK-specific contacts API.
     */
    public abstract JSONArray search(JSONArray filter, JSONObject options);

    /**
     * Handles removing a contact from the database.
     */
    public abstract boolean remove(String id);

    /**
     * A class that represents the where clause to be used in the database query 
     */
    class WhereOptions {
        private String where;
        private String[] whereArgs;

        public void setWhere(String where) {
            this.where = where;
        }

        public String getWhere() {
            return where;
        }

        public void setWhereArgs(String[] whereArgs) {
            this.whereArgs = whereArgs;
        }

        public String[] getWhereArgs() {
            return whereArgs;
        }
    }
}