com.ev.contactsmultipicker.ContactListFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.ev.contactsmultipicker.ContactListFragment.java

Source

/**
 * Copyright 2013 Ernestas Vaiciukevicius (ernestas.vaiciukevicius@gmail.com)
 *
 * 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.ev.contactsmultipicker;

import android.app.AlertDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;

import com.ev.contactsmultipicker.ContactResult.ResultItem;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;

/**
 * @author Ernestas Vaiciukevicius (ernestas.vaiciukevicius@gmail.com)
 *
 */
public class ContactListFragment extends Fragment
        implements LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener {
    private final static String SAVE_STATE_KEY = "mcListFrag";

    private final String[] projection = new String[] { Contacts._ID, Contacts.DISPLAY_NAME,
            Contacts.PHOTO_THUMBNAIL_URI };
    private final String selection = Contacts.HAS_PHONE_NUMBER + " = 1";

    private ListView mContactListView;
    private CursorAdapter mCursorAdapter;
    private Hashtable<String, ContactResult> results = new Hashtable<String, ContactResult>();

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putSerializable(SAVE_STATE_KEY, results);
    }

    public Hashtable<String, ContactResult> getResults() {
        return results;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mCursorAdapter = new ContactsCursorAdapter(getActivity(), R.layout.contact_list_item, null,
                new String[] { Contacts.DISPLAY_NAME, Contacts.PHOTO_THUMBNAIL_URI },
                new int[] { R.id.contactLabel, R.id.contactImage }, 0);

        getLoaderManager().initLoader(0, null, this);
    }

    @SuppressWarnings("unchecked")
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        if (savedInstanceState != null) {
            results = (Hashtable<String, ContactResult>) savedInstanceState.getSerializable(SAVE_STATE_KEY);
        }

        View rootView = inflater.inflate(R.layout.contact_list_fragment, container);

        mContactListView = (ListView) rootView.findViewById(R.id.contactListView);

        mContactListView.setAdapter(mCursorAdapter);
        mContactListView.setOnItemClickListener(this);

        return rootView;
    }

    @Override
    public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
        return new CursorLoader(getActivity(), Contacts.CONTENT_URI, projection, selection, null,
                Contacts.DISPLAY_NAME);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        mCursorAdapter.swapCursor(cursor);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mCursorAdapter.swapCursor(null);
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int pos, long rowId) {
        CheckBox checkbox = (CheckBox) view.findViewById(R.id.contactCheck);

        Cursor cursor = mCursorAdapter.getCursor();
        cursor.moveToPosition(pos);
        String id = cursor.getString(0);

        if (checkbox.isChecked()) {
            checkbox.setChecked(false);
            results.remove(id);
        } else {
            checkbox.setChecked(true);

            Cursor itemCursor = getActivity().getContentResolver().query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null);
            List<ContactResult.ResultItem> resultItems = new LinkedList<ContactResult.ResultItem>();

            itemCursorLoop: while (itemCursor.moveToNext()) {
                String contactNumber = itemCursor
                        .getString(itemCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                int contactKind = itemCursor
                        .getInt(itemCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                String displayName = itemCursor
                        .getString(itemCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                Bitmap image = retrieveContactPhoto(id);

                for (ResultItem previousItem : resultItems) {
                    if (contactNumber.equals(previousItem.getResult())) {
                        continue itemCursorLoop;
                    }
                }

                resultItems.add(new ContactResult.ResultItem(contactNumber, contactKind, displayName, image));
            }
            itemCursor.close();

            if (resultItems.size() > 1)

            {
                // contact has multiple items - user needs to choose from them
                chooseFromMultipleItems(resultItems, checkbox, id);
            } else {
                // only one result or all items are similar for this contact
                results.put(id, new ContactResult(id, resultItems));
            }
        }
    }

    protected void chooseFromMultipleItems(List<ContactResult.ResultItem> items, CheckBox checkbox, String id) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        ArrayList<String> itemLabels = new ArrayList<String>(items.size());

        for (ResultItem resultItem : items) {
            itemLabels.add(resultItem.getResult());
        }

        class ClickListener implements OnCancelListener, OnClickListener, OnMultiChoiceClickListener {
            private List<ContactResult.ResultItem> items;
            private CheckBox checkbox;
            private String id;
            private boolean[] checked;

            public ClickListener(List<ContactResult.ResultItem> items, CheckBox checkbox, String id) {
                this.items = items;
                this.checkbox = checkbox;
                this.id = id;
                checked = new boolean[items.size()];
            }

            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }

            @Override
            public void onClick(DialogInterface arg0, int which, boolean isChecked) {
                checked[which] = isChecked;
            }

            private void finish() {
                ArrayList<ContactResult.ResultItem> result = new ArrayList<ContactResult.ResultItem>(items.size());
                for (int i = 0; i < items.size(); ++i) {
                    if (checked[i]) {
                        result.add(items.get(i));
                    }
                }
                if (result.size() == 0) {
                    checkbox.setChecked(false);
                } else {
                    results.put(id, new ContactResult(id, result));
                }
            }

            @Override
            public void onCancel(DialogInterface dialog) {
                finish();
            }

        }

        ClickListener clickListener = new ClickListener(items, checkbox, id);

        builder.setMultiChoiceItems(itemLabels.toArray(new String[0]), null, clickListener)
                .setOnCancelListener(clickListener).setPositiveButton(android.R.string.ok, clickListener).show();
    }

    private Bitmap retrieveContactPhoto(String contactID) {
        Context context = getActivity();
        Bitmap photo = null;

        try {
            InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(
                    context.getContentResolver(),
                    ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new Long(contactID)));

            if (inputStream != null) {
                photo = BitmapFactory.decodeStream(inputStream);
                //ImageView imageView = (ImageView) findViewById(R.id.img_contact);
                //imageView.setImageBitmap(photo);
                inputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return photo;
    }

    private class ContactsCursorAdapter extends SimpleCursorAdapter {
        public ContactsCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
            super(context, layout, c, from, to, flags);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View ret = super.getView(position, convertView, parent);

            CheckBox checkbox = (CheckBox) ret.findViewById(R.id.contactCheck);

            getCursor().moveToPosition(position);
            String id = getCursor().getString(0);
            checkbox.setChecked(results.containsKey(id));
            ImageView imageView = (ImageView) ret.findViewById(R.id.contactImage);
            String imgUri = getCursor().getString(2);
            if (imgUri == null || imgUri.equals("")) {
                imageView.setImageResource(R.drawable.ic_contact_picture);
            }
            return ret;
        }
    }

}