2012-03-29 12 views
14

Mam tablicę numerów telefonów i chcę uzyskać odpowiednie nazwy kontaktów z bazy danych kontaktów.Ręczne dodawanie wierszy do kursora

W tablicy numerów telefonów mam również numery, które nie są zapisane wcześniej w bazie danych kontaktów. Na przykład;

  • 3333333 -> Tim
  • 5555555 -> Jim
  • 1111111 -> nieznany

Mam tablica zawierająca numery telefonów pokazano powyżej, a mianowicie phoneArr.

int size=phoneArr.size(); 
if(size>0){ 
     Cursor[] cursors=new Cursor[size]; 
     for(int i=0;i<size;i++){ 
      Uri contactUri1 = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneArr.get(i))); 
      cursors[i] = getContentResolver().query(contactUri1, PEOPLE_PROJECTION, null, null, " _id asc limit 1"); 
     } 
     Cursor phones=new MergeCursor(cursors); 

phones.getCount() zwraca 2 w powyższym scenariuszu. Gdy numer telefonu nie pojawia się na liście kontaktów, kursor staje się pusty i jakoś scalam je, ale nic nie wnosi. Czego chcę jest mieć kursora następująco

telefony Cursor -> {Tim Jim, 1111111}

myślę, że mogę to zrobić, dodając wiersz ręcznie w następujący sposób:

Uri contactUri1 = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneArr.get(i))); 
cursors[i] = getContentResolver().query(contactUri1, PEOPLE_PROJECTION, null, null, " _id asc limit 1"); 
if(cursors[i].getCount()==0) 
    // add the phone number manually to the cursor 

Jak mogę to osiągnąć?

Oto PEOPLE_PROJECTION

private static final String[] PEOPLE_PROJECTION = new String[] { 
    ContactsContract.PhoneLookup._ID, 
    ContactsContract.PhoneLookup.DISPLAY_NAME, 
    ContactsContract.PhoneLookup.NUMBER 
}; 
+0

proszę spojrzeć na moje rozwiązanie, i głosuj na niego, jeśli rozwiąże problem =) – elgui

+0

Proszę przejrzeć zaakceptowaną odpowiedź, wydaje się, że jest ona nieprawidłowa, zgodnie z aktualnie dostępnymi funkcjami Androida SDK. –

+0

Cóż, zanim przyjąłem odpowiedź, wydawało mi się rozsądne. Sprawdzę to, gdy mam trochę wolnego czasu. – 0x5f3759df

Odpowiedz

43

Najprostszym sposobem dodawania wierszy w kursorze jest użycie MatrixCursor i MergeCursor. Te dwie klasy pochodzą z SDK i tutaj, aby rozwiązać tego rodzaju problemy.

zasadzie to, co robisz jest:

  1. Put wiersze, które chcesz dodać w MatrixCusror
  2. Scalanie cursor i twój matrixCursor użyciem MergeCursor

Coś jak:

// Create a MatrixCursor filled with the rows you want to add. 
MatrixCursor matrixCursor = new MatrixCursor(new String[] { colName1, colName2 }); 
matrixCursor.addRow(new Object[] { value1, value2 }); 

// Merge your existing cursor with the matrixCursor you created. 
MergeCursor mergeCursor = new MergeCursor(new Cursor[] { matrixCursor, cursor }); 

// Use your the mergeCursor as you would use your cursor. 
+0

Czy umieścić to na górze metody bindView? –

+0

Myślę, że lepiej to zrobić przed przekazaniem kursora do adaptera. Zaraz po tym, jak zrobiłeś zapytanie. –

+4

dodać, co byłoby "indeks" tego nowego wiersza w 'mergeCursor'? – Nezam

1

Niestety, o ile mi wiadomo, nie ma możliwości, że można ręcznie dodać dane do kursora. Musisz sobie z tym poradzić w inny sposób.

Jedynym sposobem, że mogę myśleć, w którym można to zrobić

  • Zrób konstrukcję z pól danych, które trzeba.
  • Utwórz listę znaków i wypełnij obiekty swojej struktury danymi z kursorów i dodaj je do listy.
  • Teraz dodaj ręcznie brakujące informacje o numerze i dodaj je do listy.
  • Przekaż tę listę do adaptera, na wypadek, gdyby teraz przejdziesz do adaptera. Oczywiście musisz zmienić implementację cursoradapter na arrayadapter.
+0

To nie jest to, co chcę usłyszeć :) W każdym razie dziękuję za odpowiedź – 0x5f3759df

+0

Tak, wiem. To duży ból. Wiele przeklinałem, ponieważ stawiałem czoła temu wielokrotnie. Jeśli jednak uda Ci się znaleźć sposób dodania kursora (co naprawdę wątpię), podziel się tym postem. I jako awarię można użyć tej metody. – Shubhayu

+1

proszę spojrzeć na moje rozwiązanie, może rozwiązać problem =) – elgui

2

Znam ten stary post, ale to prawdziwy ból, że wiersze nie mogą być dodane ręcznie do kursora. Wymyśliłem surowy roztwór. To może być pomocne.

Cursor jest rzeczywiście interface i można utworzyć niestandardowy class że implements interfejs Cursor.

class ManualCursor implements Cursor{ 
     // .... 
     private Vector<String[]> rows; 

     public void addRow(String[] values){ 
      rows.add(values); 
     } 

     // Implement the necessary methods, getString(int), etc. 

     //.... 
} 

I wreszcie w kodzie

if (cursors[i].getCount() == 0){ 
    cursors[i] = new ManualCursor(); 
    cursors[i].addRow(rowValues); 
} 

To powinno wystarczyć.Ale ostrzegaj, aby to działało, musisz być mądry podczas implementowania interfejsu Cursor.

3

Używam rozwiązania, które rozwiązuje wszystkie moje różne potrzeby, a które jest prostsze niż implementacja kursora.
Oto przykład, gdzie muszę dodać dodatkowe wiersze "listy odtwarzania" do kursora, pobrane z Mediastore. Dodać indeksów wierszy w pierwszej pierwotnej kursora:

public class CursorWithExtraPlaylists extends CursorWrapper { 

public static final int ID_COLUMN_INDEX = 0; 
public static final int NAME_COLUMN_INDEX = 1; 

private int mPos = -1; 
private Context mContext; 
private Playlist[] extras; 

public CursorWithExtraPlaylists(Cursor cursor, Context context, 
     Playlist[] extras) { 
    super(cursor); 
    mContext = context; 
    this.extras = extras; 
} 

@Override 
public int getCount() { 
    return super.getCount() + extras.length; 
} 

@Override 
public int getPosition() { 
    return mPos; 
} 

@Override 
public boolean moveToFirst() { 
    return moveToPosition(0); 
} 

@Override 
public boolean moveToLast() { 
    return moveToPosition(getCount() - extras.length); 
} 

@Override 
public boolean move(int offset) { 
    return moveToPosition(mPos + offset); 
} 

@Override 
public boolean moveToPosition(int position) { 
    // Make sure position isn't past the end of the cursor 
    final int count = getCount(); 
    if (position >= count) { 
     mPos = count; 
     return false; 
    } 
    // Make sure position isn't before the beginning of the cursor 
    if (position < 0) { 
     mPos = -1; 
     return false; 
    } 
    // Check for no-op moves, and skip the rest of the work for them 
    if (position == mPos) { 
     return true; 
    } 

    mPos = position; 
    if (mPos > 0) { 
     // ok, that concerns super cursor 
     return super.moveToPosition(mPos - 1); 
    } 
    return true; 
} 

@Override 
public boolean moveToNext() { 
    return moveToPosition(mPos + 1); 
} 

@Override 
public boolean moveToPrevious() { 
    return moveToPosition(mPos - 1); 
} 

private boolean isPointingOnExtras() { 
    if (-1 == mPos || getCount() == mPos) { 
     throw new CursorIndexOutOfBoundsException(mPos, getCount()); 
    } 
    if (mPos <= extras.length - 1) { 
     // this is a request on an extra value 
     return true; 
    } 
    return false; 
} 

private Object getExtraValue(int columnIndex) { 
    switch (columnIndex) { 
    case ID_COLUMN_INDEX: 
     return extras[mPos].getId(); 
    case NAME_COLUMN_INDEX: 
     return extras[mPos].getName(mContext); 
    } 
    return null; 
} 

@Override 
public int getInt(int columnIndex) { 
    if (isPointingOnExtras()) 
     return (Integer) getExtraValue(columnIndex); 
    int res = super.getInt(columnIndex); 
    return res; 
} 

@Override 
public String getString(int columnIndex) { 

    if (isPointingOnExtras()) 
     return getExtraValue(columnIndex).toString(); 
    return super.getString(columnIndex); 
} 

public static class Playlist { 
    private int mId; 
    private int mNameResId; 

    public Playlist(int mId, int nameResId) { 
     this.mId = mId; 
     this.mNameResId = nameResId; 
    } 

    public int getId() { 
     return mId; 
    } 

    public String getName(Context mContext) { 
     return mContext.getResources().getString(mNameResId); 
    } 

} 
} 

oryginalny kursor ma 2 kolumny (Int łańcuch), więc budowanie go w szereg dodatkowych rzędów przedmiotów.

+1

to jest niesamowite .. wielkie dzięki – amithgc

Powiązane problemy