Kontakte bearbeiten - updaten

  • Antworten:6
Gelöschter Account
  • Forum-Beiträge: 5.136

16.06.2009, 13:14:59 via Website

Moin zusammen,

aufgrund einer Anfrage in einem anderen Thread hier im Forum (
Der betreffende Thread)
habe ich mich einmal auf Code-Level mit der Frage beschäftigt, wie man die FavoritenListe der G1-Kontaktliste beeinflussen kann.

Da ich in der Doku auf http://developer.android.com/ zunächst nichts definitives dazu finden konnte habe ich ein klein wenig Forschung betrieben
und dabei folgendes herausgefunden. Erstmal in wenigen Worten:

Die Einträge in der Favoritenliste der "Kontakte" basieren darauf, ob und wie oft man bereits mit einem in der Kontaktliste befindlichen
Eintrag telefoniert hat. (Achtung: Gesendete SMS zählen hier nicht dazu!) Gespeichert wird diese Kontakt-Eigenschaft in dem Feld
"People.TIMES_CONTACTED" der zu diesem Content-Provider gehörenden SqLite Datenbank.

Sobald in diesem Feld ein Wert >0 steht, landet der Eintrag in der Favoritenliste des G1. (Ich hab noch nicht herausgefunden, wie hoch das Maximum
der dort angezeigten Favoriten ist.

Nun zu, technischen Details und dem Codeschnipsel:
1//Zunaechst mal den ContentResolver vorbereiten und ihn benennen als "myCr"
2 ContentResolver myCr = getContentResolver();
3
4 //Jetzt den Cursor vorbereiten um auf die ContentDatenbank zugreifen zu können
5 Cursor cursor = myCr.query(People.CONTENT_URI, null,null,null,null);
6
7 //Hier wird nun der zuvor definierte Cursor zur Bearbeitung vorbereitet.
8 //Diese Methode hat den Vorteil das beim Ende der Activity der Cursor
9 //automatisch geschlossen wird.
10 startManagingCursor(cursor);
11
12 //Hier holen wir uns die Indexnummern der entsprechenden Datenbankfelder aus der
13 //in der zuvor definierten Cursor.query vorbereiteten Content-Quelle.
14 //Anmerkung: Der Unterschied zwischen cursor.getColumnIndex und cursor.getColumnIndexOrThrow
15 //ist der, dass ersterer eine -1 zurückgibt wenn das in der Funktion übergebene Feld nicht
16 //existiert, wogegen zweitere Funktion eine haessliche Exception wirft wenn das übergebene
17 //Feld nicht existiert.
18 int indexId = cursor.getColumnIndex(People._ID);
19 int nameIdx = cursor.getColumnIndexOrThrow(People.NAME);
20 int phoneIdx = cursor.getColumnIndexOrThrow(People.NUMBER);
21 int nrcallIdx = cursor.getColumnIndexOrThrow(People.TIMES_CONTACTED);
22 int indexNr = cursor.getColumnIndex(People.TIMES_CONTACTED);
23
24 //Vorbereiten eines Feldes um zu setzende Felder mit neuen Werten zu beschicken
25 ContentValues newValues = new ContentValues();
26
27 String[] result = new String[cursor.getCount()];
28
29 if (cursor.moveToFirst())
30 do {
31 String name = cursor.getString(nameIdx);
32 String phone = cursor.getString(phoneIdx);
33 String nrcall = cursor.getString(nrcallIdx);
34 String index = cursor.getString(indexId);
35
36 //Uri UpdateContactsUri = Uri.withAppendedPath(People.CONTENT_URI, String.valueOf(People._ID));
37 // Hier bauen wir uns die notwendige Uri zusammen. Wichtig dabei ist, dass die Uri
38 // mit dem withAppendetPath und dem Index des zu verwendeden Eintrages versehen wird!
39 // Ansonsten hagelt es naemlich eine Unsupportet Operation Exception!
40 // Im Gegensatz dazu ist dieser Index bei Inserts normalen Querys nicht notwendig!
41 Uri UpdateContactsUri = Uri.withAppendedPath(People.CONTENT_URI, index);
42
43 //Zeigt zum Experimentieren nur die UpdateContactsUri an
44 Toast.makeText(getBaseContext(), "the URI " + UpdateContactsUri,
45 Toast.LENGTH_LONG).show();
46
47 //Baut zum experimentellen Anzeigen ein StringArray auf
48 result[cursor.getPosition()] = name + " (" + phone + ") " + nrcall;
49 //Zeigt zum Experimentieren Name, Telnummer und Anzahl der bisherigen Telefonate
50 //mit dem angezeigten Kontakt an aus dem resultArray.
51 Toast.makeText(getBaseContext(), result[cursor.getPosition()].toString(),
52 Toast.LENGTH_LONG).show();
53
54
55 // Hier picken wir uns jetzt nur die Kontakte heraus, die eine People.TIMES_CONTACTED > 0
56 // haben und bereiten diese zum reset auf 0 vor.
57 if (Integer.valueOf(nrcall).intValue() > 0) {
58
59 // Mit dem vorbereiteten newValues wird das Feld People.TIMES_CONTACTED auf int(0) gesetzt
60 newValues.put(People.TIMES_CONTACTED, 0);
61
62 // Schoen in ein Try Catch Block verpackt veranlassen wird jetzt den ContentResolver
63 // das Feld People.TIMES_CONTACTED auf int(0) zu setzen
64
65 try {
66 // Die Variable test kann theoretisch noch abgefragt werden, ob auch eine
67 // Datenbankzeile von der Aenderung betroffen war. Hier ist aufgrund des
68 // vorangegangenen if Abfrage jedoch immer vom positiven Fall auszugehen.
69 // das "int test = " kann theoretisch auch weggelassen werden, waere jedoch
70 // eher schlechter Programmierstil. (Würde jedoch nochmals ein paar Byte Heap sparen)
71 int test = getContentResolver().update(UpdateContactsUri, newValues,null,null);
72
73 // Nun sicherheitshalber mal eine Systemnachricht versenden und alle interessierten
74 // Services über die Aenderung informieren!
75 getContentResolver().notifyChange(People.CONTENT_URI,null); } catch (Exception e) { // Hier geben wir sauber eine Fehlermeldung aus falls wieder // erwarten doch noch etwas schief gegangen ist. Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show(); }
76 }
77 }
78 while (cursor.moveToNext());
79
80 // Und fini .. aus Maus
81 finish();


Um das ganze zum Laufen zu bringen müssen natürlich im Manifest folgende Permissions gesetzt werden:
1<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
2<uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission>


So nun hoffe ich ja, dass dieses kleine rudimentäre Codeschnipsel dem einen oder anderen hier geholfen hat und etwas Aufklärung im Dschungel der nicht so sehr toll dokumentierten Funktionen des Android OS gibt.

Achtung WARNUNG Wer dieses Codeschnippselchen so wie hier gezeigt einsetzt auf dem echten G1 und nicht auf dem Emulator killt alle EInträge in der Kontakt Favoriten-Liste!!!!!

Feedback ist natürlich erwünscht und wie immer willkommen ;)

lg
Voss

— geändert am 16.06.2009, 13:21:18

lg Voss

Antworten
Maxim Härter
  • Forum-Beiträge: 58

17.06.2009, 18:43:18 via Website

Stark von dir, das du dir hier so viel Mühe gibst. :smug:

Antworten
Gelöschter Account
  • Forum-Beiträge: 5.136

17.06.2009, 19:21:33 via Website

Ohhh, dankeschön das hört man gerne!

Nett das Du es erwähnt hast.

lg
Voss

lg Voss

Antworten
Fabien Röhlinger
  • Admin
  • Staff
  • Forum-Beiträge: 3.855

17.06.2009, 19:47:22 via Website

Ich kann mich da nur anschließen!! Echt SUPER!

Vielen Dank!

Antworten
Kevin T.
  • Forum-Beiträge: 337

18.06.2009, 14:07:33 via Website

Wie im anderen Thread schon gesagt find ich solche Codesnippets sehr interessant ;)

Danke auch von mir!

Android ist echt ne nicht so einfacher Programmierung wie ich finde. Vielleicht liegt es nur daran das ich immer stundenlange in de Google Javadoc suchen muss bis ich finde was ich suche :(
Aber irgendwann find ich es dann doch :D

Antworten
Gelöschter Account
  • Forum-Beiträge: 5.136

18.06.2009, 15:12:24 via Website

Ich denke das mit der Sucherei in den Javadocs wird sich mit ein kleine wenig Erfahrung legen. Irgendwann weiss man wo man suchen muss und dann gehts recht flott.

Allerdings finde ich die Doku insgesamt auch ziemlich unvollständig und teilweise auch sehr lückenhaft.

Man ist bisweilen sehr stark darauf angewiesen herumzuprobieren, weil die Javadocs in vielen Bereichen doch sehr rudimentär sind und gewisse Vorraussetzungen einfach nicht berücksichtigen.

lg
Voss

lg Voss

Antworten
Kevin T.
  • Forum-Beiträge: 337

18.06.2009, 16:21:40 via Website

Ja hinzu kommt das ich mich das erstmal wirklich mit Javadoc bzw. die Doku beschäftige.
Ich hab zwar immer Javadoc konform programmiert hab mich aber nie wirklich interessiert wie das dann aussieht und welche Rückschlüsse andere Programmierer daraus machen müssen.
Aber ich fuxx mich da schon durch ;)

Antworten