1
votes

I trying out the ListViewexample found in the Android API guide. More or less I've copied the code from the example into an activity (I only left out the progressbar for now).

Everything works, except that the ListView shows duplicates of each contact that I have on my device (running a Nexus 7, with Android 4.2).

Each contact get's duplicated 6-7 times in the listview. The cursor I'm using already returns too many results (it should only return 3 items as I only have three contacts on my Nexus atm.). When I checked the RAW_CONTACT_ID the duplicates always point to the same id values (i.e. I only get 3 unique ID's).

This would suggest that it's not my view code which has some problem.

So the question is what could be going wrong in the adapter?

Why is the cursor returning duplicates for all the contacts? Or is there something on the device that causes these duplicates to be returned.

I've looked through other questions on SO but none seem to be about this particular issue.

public class ThemeSelectorActivity extends ListActivity 
                                    implements LoaderManager.LoaderCallbacks{

    private static final String TAG = "ThemeSelector";

    // The rows that we will retrieve from the db (Contacts used as dummy data)
    static final String[] PROJECTION = new String[] {ContactsContract.Data._ID,
            ContactsContract.Data.DISPLAY_NAME};

    // The select criteria for fetching contacts
    static final String SELECTION = "((" + 
            ContactsContract.Data.DISPLAY_NAME + " NOTNULL) AND (" +
            ContactsContract.Data.DISPLAY_NAME + " != '' ))";

    // The Adapter being used to display the list's data
    SimpleCursorAdapter mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        Log.d(TAG, "Create...");

        super.onCreate(savedInstanceState);

        // set the listview to be selectable
        getListView().setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);

        // For the cursor adapter, specify which columns go into which views
        String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME};
        int[] toViews = {android.R.id.text1}; // The TextView in simple_list_item_1

        // Create an empty adapter we will use to display the loaded data.
        // We pass null for the cursor, then update it in onLoadFinished()
        mAdapter = new SimpleCursorAdapter(this, 
                android.R.layout.simple_list_item_1, null,
                fromColumns, toViews, 0);

        setListAdapter( mAdapter );

        // Prepare the loader.  Either re-connect with an existing one,
        // or start a new one.
        getLoaderManager().initLoader(0, null, this);
    }

    // Called when a new Loader needs to be created
    public Loader onCreateLoader(int id, Bundle args) {
        // Now create and return a CursorLoader that will take care of
        // creating a Cursor for the data being displayed.
        return new CursorLoader(this, ContactsContract.Data.CONTENT_URI,
                PROJECTION, SELECTION, null, null);
    }

    // Called when a previously created loader has finished loading
    public void onLoadFinished(Loader loader, Cursor data) {
        // Swap the new cursor in.  (The framework will take care of closing the
        // old cursor once we return.)
        mAdapter.swapCursor(data);
    }

    // Called when a previously created loader is reset, making the data unavailable
    public void onLoaderReset(Loader loader) {
        // This is called when the last Cursor provided to onLoadFinished()
        // above is about to be closed.  We need to make sure we are no
        // longer using it.
        mAdapter.swapCursor(null);
    }

    @Override
    /**
     * Start activity that shows a preview of the selected theme
     */
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        //String item = (String) getListAdapter().getItem(position);
        //Toast.makeText(this, item + " selected", Toast.LENGTH_LONG).show();
    }   
}
1
As I said, it's basically a copy of the sample that I linked to (developer.android.com/guide/topics/ui/layout/…), only removing the progress indicator for now. But updated the question for completeness sakeJens Wegar
sample works. Your code basically not.Marcin Orlowski
Just to make sure I'm not missing something trivial in my test, I created a new Android project (API level 15, min SDK version 14) in Eclipse, just stepped through the new project wizard. Then copy-pasted all the code from the Example, changed the name of the class from ListViewLoader to MainActivity (to match the start activity), added the read privileges to the manifest and then ran the sample. Same result as before, i.e. the list of contacts shows up, but each is duplicated several time. Any thoughts?Jens Wegar

1 Answers

2
votes

ContactsContract.Data.CONTENT_URI is show all data of contact

you should use ContactsContract.Contacts.CONTENT_URI