Frage

I'm trying to make an AutoCompleteTextView witch will complete user input from the contacts list, I made it but it caused a big preformence damage.

I tried to use CursorLoader (https://developer.android.com/training/load-data-background/setup-loader.html)

the app is now force closing:

 07-30 05:02:45.034: E/AndroidRuntime(1396): FATAL EXCEPTION: main
 07-30 05:02:45.034: E/AndroidRuntime(1396): java.lang.ClassCastException:  
 android.content.CursorLoader cannot be cast to android.database.Cursor 

CODE:

@Override
public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle)
{
    /*
     * Takes action based on the ID of the Loader that's being created
     */
    switch (loaderID) {
        case NAMES_LOADER:
            // Returns a new CursorLoader
            CursorLoader peopleCursor = new CursorLoader(
                        context,   // Parent activity context
                        ContactsContract.Contacts.CONTENT_URI,        // Table to query
                        null,     // Projection to return
                        null,            // No selection clause
                        null,            // No selection arguments
                        null             // Default sort order
        );

            while (((Cursor) peopleCursor).moveToNext()) {
                contactName = ((Cursor) peopleCursor).getString(((Cursor)  peopleCursor)
                        .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
               contactId = ((Cursor) peopleCursor).getString(((Cursor) peopleCursor)
                        .getColumnIndex(ContactsContract.Contacts._ID));
                hasPhone = ((Cursor) peopleCursor)
                        .getString(((Cursor) peopleCursor)
                                .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
            }



        case PHONES_LOADER:
             if ((Integer.parseInt(hasPhone) > 0)){
            CursorLoader phonesCursor = new CursorLoader(
                    context, // Parent activity context
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,        // Table to query
                    null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, // Projection to return
                    null,            // No selection clause
                    null            // No selection arguments
                                 // Default sort order
    );

            while (((Cursor) phonesCursor).moveToNext()){
                //store numbers and display a dialog letting the user select which.
                String phoneNumber = ((Cursor) phonesCursor).getString(
                        ((Cursor) phonesCursor).getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                Map<String, String> NamePhoneType = new ContactMap();
                NamePhoneType.put("Name", contactName);
                NamePhoneType.put("Phone", phoneNumber);

                    mPeopleList.add(NamePhoneType);
            }

             }
        default:
            // An invalid id was passed in
            return null;
    }
}  

this is the error part:

 while (((Cursor) peopleCursor).moveToNext()) {
            contactName = ((Cursor) peopleCursor).getString(((Cursor)  peopleCursor)
                    .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
           contactId = ((Cursor) peopleCursor).getString(((Cursor) peopleCursor)
                    .getColumnIndex(ContactsContract.Contacts._ID));
            hasPhone = ((Cursor) peopleCursor)
                    .getString(((Cursor) peopleCursor)
                            .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
        }

the error is because I'm casting Cursor to CursorLoader, I cant find another way to do it because the methhoodes I need are not avalible in the type CursorLoader.

does anyone have a solution? or another way to auto complete contacts without damaging preformence? thanks!

War es hilfreich?

Lösung

Since no one else has offered an answer, let me suggest populating your array in onLoaderFinish after the cursor has been created. The Cursor Loader is essentially a query statement and not the results, which is why you can't cast from a CursorLoader to a Cursor.

Andere Tipps

The below code is what I use to populate my AutoCompleteTextView with all email addresses on my device.

It shows how to use the LoaderCallbacks<Cursor> interface methods, and is based on the template LoginActivity supplied by the SDK (in Eclipse: File...New... Android Activity... Login).


Preparing the CursorLoader:

/**
 * Creates a new {@link CursorLoader} that reads email addresses from the device contact list.
 */
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle)
{
    /* URI for the device profile contact only - not used in this activity */
    @SuppressWarnings("unused")
    Uri uriDeviceProfileContact =
            Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
                    ContactsContract.Contacts.Data.CONTENT_DIRECTORY);

    /* URI for all contacts on the device */
    Uri uriAllContacts = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
    CursorLoader profileLoader =
            new CursorLoader(this, uriAllContacts, ProfileQuery.PROJECTION,
                    ContactsContract.Contacts.Data.MIMETYPE + " = ?", new String[]
                        { ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE },
                    ContactsContract.CommonDataKinds.Email.ADDRESS);

    return profileLoader;
}

Note that this only defines what should be loaded - it does not attempt to populate any data structures.


Process results:

/**
 * Adds loaded email addresses to the autocomplete field.
 */
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor)
{
    List<String> emails = new ArrayList<String>();
    cursor.moveToFirst();
    while (!cursor.isAfterLast())
    {
        emails.add(cursor.getString(ProfileQuery.ADDRESS));
        cursor.moveToNext();
    }

    addEmailsToAutoComplete(emails);
}

private void addEmailsToAutoComplete(List<String> emailAddressCollection)
{
    // Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
    ArrayAdapter<String> adapter =
            new ArrayAdapter<String>(InterviewMethodTest.this,
                    android.R.layout.simple_dropdown_item_1line, emailAddressCollection);

    myAutoCompleteField.setAdapter(adapter);
}

I do not make use of the onLoaderReset(Loader<Cursor>) method.


The above code requires the following projection of the data to the cursor:

/**
 * Defines the mappings used to get the email addresses from the contact list.
 */
private interface ProfileQuery
{
    /** Columns to fetch from the database into the cursor. */
    String[] PROJECTION =
        { ContactsContract.CommonDataKinds.Email.ADDRESS,
                ContactsContract.CommonDataKinds.Email.IS_PRIMARY, };

    /** Column in cursor of the address. */
    int ADDRESS = 0;

    /** Column in cursor of the primary email address indicator. */
    @SuppressWarnings("unused")
    int IS_PRIMARY = 1;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top