2010-01-28 3 views
31

Ich möchte Benutzerkontakte erhalten und dann eine Art von regulären Ausdruck anfügen und sie an eine Listenansicht anhängen. Ich bin derzeit in der Lage überWie filtern Sie die Ergebnisse von Content Resolver in Android?

getContentResolver().query(People.CONTENT_URI, null, null, null, null);

alle Kontakte zu bekommen und sie dann in eine eigene Klasse übergeben, die SimpleCursorAdapter erstreckt.

So würde ich gerne wissen, wie man nur die Kontakte erhalten, die einen regulären Ausdruck und nicht alle Benutzer Kontakte entsprechen.

Antwort

63

Statt

getContentResolver().query(People.CONTENT_URI, null, null, null, null); 

Sie so etwas wie

final ContentResolver resolver = getContentResolver(); 
final String[] projection = { People._ID, People.NAME, People.NUMBER }; 
final String sa1 = "%A%"; // contains an "A" 
cursor = resolver.query(People.CONTENT_URI, projection, People.NAME + " LIKE ?", 
    new String[] { sa1 }, null); 

diese verwendet eine parametrisierte Anfrage (mit ?) und liefert die aktuellen Werte als ein anderes Argument verwenden sollten, dies vermeidet Verkettung und verhindert SQL Injektion vor allem, wenn Sie den Filter vom Benutzer anfordern. Wenn Sie zum Beispiel verwenden

cursor = resolver.query(People.CONTENT_URI, projection, 
    People.NAME + " = '" + name + "'", 
    new String[] { sa1 }, null); 

vorstellen, wenn

name = "Donald Duck' OR name = 'Mickey Mouse") // notice the " and ' 

und Sie die Saiten sind verketten.

+0

Vielen Dank für Ihre Antworten Ich schätze es wirklich. – maxsap

+2

Sehr schöne Erklärung, vielen Dank! –

5

Sie können den Inhaltsanbieter mit der Eingabe sql type abfragen, die Query-Methode ist nur ein Wrapper für einen SQL-Befehl. Hier

ist ein Beispiel, wo ich für einen Kontaktnamen abfragen gegeben eine bestimmte Anzahl

String [] requestedColumns = { 
      Contacts.Phones.NAME, 
      Contacts.Phones.TYPE 
    }; 

Cursor contacts = context.getContentResolver().query(
      Contacts.Phones.CONTENT_URI, 
      requestedColumns, 
      Contacts.Phones.NUMBER + "='" + phoneNumber + "'", 
      null, null); 

Hinweis, dass anstelle von null I Parameter, die die SQL-Anweisung aufzubauen.

Die requestColumns sind die Daten, die ich zurück zu bekommen und Contacts.Phones.NUMBER + „=‚“+ Telefonnummer anzeigen +„‘“ ist der Where-Klausel, so dass ich Abrufen der Name und Typ, wo die Telefonnummer übereinstimmt

3

Sie sollten in der Lage sein, eine legale SQLite WHERE-Klausel als drittes Argument in die query() -Methode einzufügen, einschließlich LIKE, aber in SQLite gibt es keine native REGEXP-Funktion, und Android scheint Sie nicht zu definieren. Je nachdem, wie komplex Ihre Anforderungen sind, könnte eine Reihe anderer SQLite-Bedingungen und LIKE-Ausdrücke den Zweck erfüllen.

Siehe die Dokumentation zu query method unter ContentResolver und SQLite expressions.

1

Eigentlich funktioniert REGEXP mit Calllog Content Provider (bedeutet, dass die regexp() - Funktion für die Datenbank dieses Content-Providers definiert ist https://sqlite.org/lang_expr.html#regexp)! Aber es ist sehr langsam: ~ 15 Sekunden über ~ 1750 Aufzeichnungen.

String regexp = "([\\s\\S]{0,}" + 
TextUtils.join("||[\\s\\S]{0,}", numbers) + 
")"; 

cursor = context.getContentResolver().query(
CallLog.Calls.CONTENT_URI, 
null, 
CallLog.Calls.NUMBER + " REGEXP ?", 
new String[]{regexp}, 
CallLog.Calls.DATE + " DESC" 
); 
Verwandte Themen