Sierpień 29, 2011
Content Providers Podstawowe komponenty Tutoriale
Dostawcy treści w Androidzie to abstrakcyjna warstwa ułatwiająca dostęp do danych zapisanych w urządzeniu. Content Providers (ang.) dostarczają nam interfejsu zarządzania danymi opartego o adresy URI (które wykorzystują schemat content://). Dzięki nim w łatwy sposób możemy oddzielić warstwę aplikacji od warstwy dostępu do danych. Co więcej, mechanizm ten pozwala nam na dzielenie się danymi pomiędzy wszystkimi aplikacjami działającymi w systemie (i posiadającymi odpowiednie uprawnienia).
Android sam w sobie posiada kilku wbudowanych dostawców treści, którzy ułatwiają nam dostęp m.in. do:
Każde z powyższych (i wiele innych) posiada własną bazę danych SQLite umieszczoną w pamięci naszego urządzenia. Dzięki dostawcom, dostęp do powyższych danych jest ustandaryzowany i możliwy z każdej aplikacji naszego urządzenia. I, co najważniejsze, jest na tyle prosty, że po zapoznaniu z jednym z dostawców, będziemy potrafili korzystać z każdego innego.
Dzisiejszy wpis będzie wprowadzeniem do obsługi dostawców treści (na przykładzie dostępu do listy kontaktów).
Dostęp do danych za pomocą dostawców treści opiera się o adresację URI. Na ich podstawie określany jest zarówno konkretny dostawca, z którego chcemy skorzystać jak i dane, które chcemy wydobyć (ich zbiór lub pojedynczy rekord).
Każdy adres URI składa się z 3 części – (1)content://(2)<nazwa dostawcy>/(3)<pozostałe segmenty adresu>
Warto wspomnieć o tym, że adresy URI mogą być nieco bardziej złożone od tych, które przedstawiłem powyżej. Oprócz wszystkich i pojedynczego rekordu można również wstępnie definiować filtry dla zbioru danych itp. Dostawcy treści mają możliwość traktowania każdego segmentu jako osobnego argumentu dla funkcji przetwarzających dane, w związku z czym mamy tu ogromne pole manewru.
Do uzyskania dostępu do danych wykorzystywany jest mechanizm ContentResolver. Dostarcza nam on wszystkich potrzebnych metod umożliwiających operacje na danych (odczyt, zapis, usuwanie, aktualizowanie). Każdy kontekst aplikacji przechowuje instancję klasy ContentResolver, do której dostęp odbywa się poprzez wywołanie metody getContentResolver() (możemy ją wywołać zarówno na kontekście całej aplikacji jak i kontekście konkretnego komponentu – np. Aktywności).
Metody klasy ContentResolver, które operują na danych (np. query(), insert(), delete(), update()) jako jeden z argumentów przyjmują adres URI. Na jego podstawie ContentResolver decyduje z którego dostawcy treści ma skorzystać.
Dostęp do danych za pomocą dostawców treści jest bardzo podobny do standardowych zapytań SQL. Dane zwracane są w postaci obiektu Cursor, który pozwala nam na „chodzenie” po wszystkich zwróconych wierszach danych (dokumentacja klasy Cursor).
Oto typowe zapytanie pobierające zbiór kontaktów z naszego urządzenia:
Metoda zwraca nam obiekt kursora w którym przechowywane są wszystkie zwrócone rekordy. Argumenty metody query() to (w kolejności):
Powyższy kod źródłowy zwróci nam wszystkie surowe kontakty, które nie zostały oznaczone jako „do usunięcia”. Zwrócone zostaną dwie kolumny – id oraz wyświetlana nazwa. Posortowane zostaną w kolejności alfabetycznej.
Aby dodać dane za pomocą dostawcy treści, oprócz zdefiniowanego adresu URI (wskazującego na miejsce, gdzie dane mają być zapisane) powinniśmy dostarczyć obiekt klasy ContentValues. Przechowuje on pary klucz-wartość odpowiadające nazwie kolumny i wartości, która ma być do niej wpisana.
Przykładowy kod dodający do bazy surowy kontakt (posiadający jedynie imię i nazwisko) wygląda mniej więcej tak:
Jak widać, wykonywane tu są dwa zapytania. Jedno tworzy nowy kontakt (bez żadnych danych). Drugie natomiast, na podstawie zwróconego adresu URI (metoda insert zwraca adres URI wskazujący na nowo dodany rekord) dodaje dane dodatkowe, w postaci imienia i nazwiska.
Aktualizacja danych również polega na wykorzystaniu adresu URI oraz zbioru danych ContentValues. Dodatkowo należy dostarczyć warunek, na podstawie którego wiadomo będzie, które wiersze należy zaktualizować. Zaktualizowane zostaną wszystkie kolumny na które wskazuje ContentValues we wszystkich wierszach pasujących do warunku.
Przykład metody aktualizującej imię oraz nazwisko surowego kontaktu wygląda tak:
Zgodnie z powyższym kodem zaktualizowane zostaną kolumny GIVEN_NAME, FAMILY_NAME, oraz DISPLAY_NAME wierszy, których id kontaktu będzie równe zmiennej contactId.
Metoda update() zwróci nam ilość zaktualizowanych wierszy.
Usuwanie jest chyba najprostszą czynnością. Metodzie delete() należy dostarczyć jedynie adres URI oraz warunek, który wiersze muszą spełnić aby zostać usuniętym. Przykład usuwający pojedynczy kontakt wygląda tak:
Powyższe operacje wykorzystamy w prostej aplikacji, która pozwoli na dodawanie, usuwanie oraz edytowanie kontaktów.
Zaczniemy od stworzenia layoutu dla czterech elementów – okna Aktywności, wiersza w ListView, okna dialogowego dla edycji oraz dodawania kontaktu.
main.xml
contact_row.xml
new_contact_dialog.xml
edit_contact_dialog.xml
Adapter listy kontaktów zbudowany jest zgodnie z zasadami wydajnościowymi (recykling widoku, jednokrotne wykonanie findViewById()). Artykuł z tym związany można przeczytać pod tym adresem.
Zaznaczony kod źródłowy odpowiedzialny jest za obsługę kliknięć przycisków dla poszczególnych wierszy listy.
Oto kompletny kod źródłowy głównej Aktywności. Wykorzystane tu zostały metody opisane w niniejszym wpisie (podkreślone w kodzie).
Kod źródłowy przykładowej aplikacji można znaleźć na naszym Githubie – HelloContentProviders.
Świetny artykuł, tego mi brakowało. A czy wiesz, może jak wstawić jakies moje dane do kontaktu, tak jak np. zrobił to facebook z profilem? Albo na przykład dodatkowe dane wymyślone przeze mnie, np. model telefonu i żeby były w androidowej książce telefonicznej?
Ja w takim wypadku skorzystałbym z tabeli reprezentowanej przez ContactsContract.Data, gdzie do kilkunastu kolumn można dodawać różne informacje a za pomocą pola MimeType określać co to za typ danych.
Witam, temat wpisu jaki wszystkich pozostałych naprawdę bardzo fajnie opracowane, można wiele ciekawych rzeczy wyciągnąć Mam jednak pytanie a skąd ten magic number „contactsCursor.getString(1)” dlaczego akurat 1?
Ta magiczna liczba to nic innego jak indeks. Resztę sam sobie dopisz
Zaloguj się lub skorzystaj z profilu:
Możesz również zostawić komentarz bez rejestracji, korzystając z poniższego formularza:
Musisz być zalogowany aby móc pisać komentarze.
Content Providers – dostęp do danych przy pomocy dostawców treści
Powiązane linki
Adresy URI
Dostęp do danych
Przykładowa aplikacja
Kod źródłowy Aktywności
Zrzuty ekranu
Pobieranie danych
Dodawanie danych
Aktualizacja danych
Usuwanie danych
Layout
Adapter listy kontaktów
Kompletny kod źródłowy
Komentarze (4)
Prześlij komentarz
- Kontaktów,
- Historii połączeń
- Danych multimedialnych (muzyka, zdjęcia)
- Ustawień
- content://com.android.contacts/contacts/7 – wskazuje na konkretny kontakt (o id = 7)
- content://com.example.provider.myprovider/items – wskazuje na cały zbiór danych (tablę) items.
- Adres URI wskazujący na dostawcę treści i dane. W przykładzie korzystamy z tabeli RawContacts (dokumentacja). Przechowuje ona informacje o pojedynczym kontakcie (tzw. surowy kontakt). Czasami prawdziwy kontakt w telefonie składa się ze zbioru kilku surowych kontaktów.
- Tablica projection – przechowuje ona nazwy kolumn, które chcemy pobrać w naszym zapytaniu. Jeżeli ustawimy ją na null (nie polecane bez uzasadnienia) zwrócone zostaną wszystkie dostępne kolumny z tabeli.
- Ciąg selection – odpowiada klauzuli WHERE z języka SQL. Możemy wykorzystywać tu znak zapytania jako argument, do którego następnie zostaną wpisane dane z kolejnego argumentu – selectionArgs.
- Tablica selectionArgs – argumenty wykorzystywane w ciągu selection. Wpisywane są w takiej samej kolejności, w jakiej są zadeklarowane.
- Ciąg sortOrder – odpowiada klauzuli ORDER BY języka SQL.
- content:// – to stały prefiks mówiący o tym, że chcemy skorzystać z dostawcy danych
- <nazwa dostawcy>/ – segment wskazujący na konkretnego dostawcę danych. Na jego podstawie określany jest dostawca, którego będziemy prosić o dane.
Istnieją dwa typy powyższego segmentu: - <pozostałe segmenty adresu> – tutaj określamy dane jakie chcemy uzyskać. Ta część adresu może składać się z jednego lub więcej segmentów. Za ich pomocą możemy określać zarówno zbiór danych jak i pojedyncze rekordy. Przykładowe adresy to:
- Proste, czyli składające się najczęściej z jednego słowa (media, contacts, itp). Określają one dostawców treści dostarczonych przez twórców systemu.
- Złożone – ich nazwa to najczęściej pełna nazwa klasy dostawcy (wraz z pakietem). Są to dostawcy zdefiniowani przez niezależnych twórców aplikacji. Przykład takiego adresu to content://com.example.provider.myprovider/.
ContentResolver contentResolver = getContentResolver();
private Cursor getContactsCursor() {
Uri uri = RawContacts.CONTENT_URI;
String[] projection = { RawContacts._ID, Contacts.DISPLAY_NAME };
String selection = RawContacts.DELETED + "=?";
String[] selectionArgs = { Integer.toString(0) };
String sortOrder = Contacts.DISPLAY_NAME + " ASC";
return contentResolver.query(uri, projection, selection, selectionArgs, sortOrder);
}private void addNewContact() {
String firstName = dialogEtFirstName.getText().toString();
String lastName = dialogEtLastName.getText().toString();
ContentValues values = new ContentValues();
Uri rawContactUri = contentResolver.insert(RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
values.clear();
values.put(RawContacts.Data.RAW_CONTACT_ID, rawContactId);
values.put(RawContacts.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
values.put(StructuredName.DISPLAY_NAME, firstName + " " + lastName);
contentResolver.insert(Data.CONTENT_URI, values);
}private void updateCurrentContact() {
String firstName = dialogEtFirstName.getText().toString();
String lastName = dialogEtLastName.getText().toString();
ContentValues values = new ContentValues();
values.put(CommonDataKinds.StructuredName.GIVEN_NAME, firstName);
values.put(CommonDataKinds.StructuredName.FAMILY_NAME, lastName);
values.put(CommonDataKinds.StructuredName.DISPLAY_NAME, firstName + " " + lastName);
String where = ContactsContract.Data.RAW_CONTACT_ID + "=? AND "
+ ContactsContract.Data.MIMETYPE + "=?";
String[] selectionArgs = {
Long.toString(contactId),
CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
};
contentResolver.update(ContactsContract.Data.CONTENT_URI, values, where, selectionArgs);
}private void deleteCurrentContact() {
String where = RawContacts._ID + "=" + contactId;
contentResolver.delete(RawContacts.CONTENT_URI, where, null);
}<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:layout_height="fill_parent" android:layout_weight="1" android:layout_width="fill_parent" android:id="@android:id/list" android:drawSelectorOnTop="false"></ListView> <Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/btnAddNewContact" android:text="Add new contact"></Button> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="50dp" android:padding="2dp"> <TextView android:textAppearance="?android:attr/textAppearanceMedium" android:id="@+id/tvDisplayName" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_vertical" android:layout_marginRight="1dp" android:paddingLeft="10dp" android:text="---"></TextView> <ImageButton android:src="@android:drawable/ic_menu_edit" android:layout_height="fill_parent" android:layout_width="50dp" android:layout_marginRight="1dp" android:id="@+id/ibEdit" android:background="@android:drawable/list_selector_background"></ImageButton> <ImageButton android:src="@android:drawable/ic_delete" android:layout_height="fill_parent" android:layout_width="50dp" android:id="@+id/ibDelete" android:background="@android:drawable/list_selector_background"></ImageButton> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/layout_root"> <TextView android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_height="wrap_content" android:padding="5dp" android:text="Firstname"></TextView> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPersonName" android:id="@+id/etFirstNameAdd" android:hint="Type firstname here..."> <requestFocus></requestFocus> </EditText> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_height="wrap_content" android:padding="5dp" android:text="Lastname"></TextView> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPersonName" android:id="@+id/etLastNameAdd" android:hint="Type lastname here..."></EditText> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/layout_root"> <TextView android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_height="wrap_content" android:padding="5dp" android:text="Firstname"></TextView> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPersonName" android:id="@+id/etFirstNameEdit"> <requestFocus></requestFocus> </EditText> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_height="wrap_content" android:padding="5dp" android:text="Lastname"></TextView> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPersonName" android:id="@+id/etLastNameEdit"></EditText> </LinearLayout>
package pl.froger.hello.contentprovider;
import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
public class ContactListAdapter extends SimpleCursorAdapter {
private Context context;
private Cursor c;
private int displayNameColumnIndex;
private OnClickListener onItemEditClickListener;
private OnClickListener onItemDeleteClickListener;
public ContactListAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.context = context;
this.c = c;
displayNameColumnIndex = c.getColumnIndex(Contacts.DISPLAY_NAME);
}
static class ViewHolder {
TextView tvDisplayName;
ImageButton ibEditContact;
ImageButton ibDeleteContact;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
View rowView = convertView;
if(rowView == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = layoutInflater.inflate(R.layout.contact_row, null, true);
viewHolder = new ViewHolder();
viewHolder.tvDisplayName = (TextView) rowView.findViewById(R.id.tvDisplayName);
viewHolder.ibEditContact = (ImageButton) rowView.findViewById(R.id.ibEdit);
viewHolder.ibDeleteContact = (ImageButton) rowView.findViewById(R.id.ibDelete);
viewHolder.ibEditContact.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(onItemEditClickListener != null) onItemEditClickListener.onClick(v);
}
});
viewHolder.ibDeleteContact.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(onItemDeleteClickListener != null) onItemDeleteClickListener.onClick(v);
}
});
rowView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) rowView.getTag();
}
c.moveToPosition(position);
viewHolder.tvDisplayName.setText(c.getString(displayNameColumnIndex));
viewHolder.ibEditContact.setTag(new Integer(position));
viewHolder.ibDeleteContact.setTag(new Integer(position));
return rowView;
}
public void setOnItemDeleteClickListener(
OnClickListener onItemDeleteClickListner) {
this.onItemDeleteClickListener = onItemDeleteClickListner;
}
public void setOnItemEditClickListener(
OnClickListener onItemEditClickListener) {
this.onItemEditClickListener = onItemEditClickListener;
}
}package pl.froger.hello.contentprovider;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends ListActivity {
private static final int DIALOG_EDIT = 1;
private static final int DIALOG_DELETE = 2;
private static final int DIALOG_CREATE = 3;
private Button btnAddNewContact;
private View editDialogView;
private View addDialogView;
private EditText dialogEtFirstNameEdit;
private EditText dialogEtLastNameEdit;
private EditText dialogEtFirstNameAdd;
private EditText dialogEtLastNameAdd;
private ContentResolver contentResolver;
private Cursor contactsCursor;
private ContactListAdapter adapter;
private int currentContactPosition = 0;
private OnClickListener onItemDeleteClickListener = new OnClickListener() {
public void onClick(View v) {
currentContactPosition = (Integer) v.getTag();
showDialog(DIALOG_DELETE);
}
};
private OnClickListener onItemEditClickListener = new OnClickListener() {
public void onClick(View v) {
currentContactPosition = (Integer) v.getTag();
contactsCursor.moveToPosition(currentContactPosition);
dialogEtFirstNameEdit.setText(getFirstNameOfCurrentContact());
dialogEtLastNameEdit.setText(getLastNameOfCurrentContact());
showDialog(DIALOG_EDIT);
}
};
private String getFirstNameOfCurrentContact() {
String displayName = contactsCursor.getString(1);
String[] tokens = displayName.split(" ");
if(tokens != null && tokens.length > 0) {
return tokens[0];
}
return "";
}
private String getLastNameOfCurrentContact() {
String displayName = contactsCursor.getString(1);
String[] tokens = displayName.split(" ");
if(tokens != null && tokens.length > 1) {
return tokens[tokens.length - 1];
}
return "";
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnAddNewContact = (Button) findViewById(R.id.btnAddNewContact);
btnAddNewContact.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dialogEtFirstNameEdit.setText("");
dialogEtLastNameEdit.setText("");
showDialog(DIALOG_CREATE);
}
});
initDialogViews();
initDialogFields();
contentResolver = getContentResolver();
contactsCursor = getContactsCursor();
startManagingCursor(contactsCursor);
fillListView();
}
private void initDialogViews() {
LayoutInflater inflater = this.getLayoutInflater();
addDialogView = inflater.inflate(R.layout.new_contact_dialog,
(ViewGroup) findViewById(R.id.layout_root));
editDialogView = inflater.inflate(R.layout.edit_contact_dialog,
(ViewGroup) findViewById(R.id.layout_root));
}
private void initDialogFields() {
dialogEtFirstNameEdit = (EditText) editDialogView.findViewById(R.id.etFirstNameEdit);
dialogEtLastNameEdit = (EditText) editDialogView.findViewById(R.id.etLastNameEdit);
dialogEtFirstNameAdd = (EditText) addDialogView.findViewById(R.id.etFirstNameAdd);
dialogEtLastNameAdd = (EditText) addDialogView.findViewById(R.id.etLastNameAdd);
}
private Cursor getContactsCursor() {
Uri uri = RawContacts.CONTENT_URI;
String[] projection = { RawContacts._ID, Contacts.DISPLAY_NAME };
String selection = RawContacts.DELETED + "=?";
String[] selectionArgs = { Integer.toString(0) };
String sortOrder = Contacts.DISPLAY_NAME + " ASC";
return contentResolver.query(uri, projection, selection, selectionArgs, sortOrder);
}
private void fillListView() {
adapter = new ContactListAdapter(getApplicationContext(), R.layout.contact_row,
contactsCursor, new String[0], new int[0]);
adapter.setOnItemDeleteClickListener(onItemDeleteClickListener);
adapter.setOnItemEditClickListener(onItemEditClickListener);
setListAdapter(adapter);
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_EDIT:
return getEditDialog();
case DIALOG_DELETE:
return getDeleteDialog();
case DIALOG_CREATE:
return getCreateDialog();
default:
return null;
}
}
private Dialog getEditDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
contactsCursor.moveToPosition(currentContactPosition);
builder.setTitle("Edit contact");
builder.setView(editDialogView);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
updateCurrentContact();
adapter.notifyDataSetChanged();
}
});
builder.setNegativeButton("Cancel", null);
return builder.create();
}
private void updateCurrentContact() {
contactsCursor.moveToPosition(currentContactPosition);
long contactId = contactsCursor.getLong(0);
String firstName = dialogEtFirstNameEdit.getText().toString();
String lastName = dialogEtLastNameEdit.getText().toString();
ContentValues values = new ContentValues();
values.put(CommonDataKinds.StructuredName.GIVEN_NAME, firstName);
values.put(CommonDataKinds.StructuredName.FAMILY_NAME, lastName);
values.put(CommonDataKinds.StructuredName.DISPLAY_NAME, firstName + " " + lastName);
String where = ContactsContract.Data.RAW_CONTACT_ID + "=? AND "
+ ContactsContract.Data.MIMETYPE + "=?";
String[] selectionArgs = {
Long.toString(contactId),
CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
};
contentResolver.update(ContactsContract.Data.CONTENT_URI, values, where, selectionArgs);
}
private Dialog getDeleteDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Are you sure ?");
builder.setMessage("Do you really want to delete this contact?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteCurrentContact();
adapter.notifyDataSetChanged();
}
});
builder.setNegativeButton("No", null);
return builder.create();
}
private void deleteCurrentContact() {
contactsCursor.moveToPosition(currentContactPosition);
long contactId = contactsCursor.getLong(0);
String where = RawContacts._ID + "=" + contactId;
contentResolver.delete(RawContacts.CONTENT_URI, where, null);
}
private Dialog getCreateDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Create new contact");
builder.setView(addDialogView);
dialogEtFirstNameAdd.setText("");
dialogEtLastNameAdd.setText("");
builder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
addNewContact();
adapter.notifyDataSetChanged();
}
});
builder.setNegativeButton("Cancel", null);
return builder.create();
}
private void addNewContact() {
String firstName = dialogEtFirstNameAdd.getText().toString();
String lastName = dialogEtLastNameAdd.getText().toString();
ContentValues values = new ContentValues();
Uri rawContactUri = contentResolver.insert(RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
values.clear();
values.put(RawContacts.Data.RAW_CONTACT_ID, rawContactId);
values.put(RawContacts.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
values.put(StructuredName.DISPLAY_NAME, firstName + " " + lastName);
contentResolver.insert(Data.CONTENT_URI, values);
}
}
29 sierpnia 2011 o 09:23
31 sierpnia 2011 o 18:08
7 listopada 2011 o 20:55
8 stycznia 2012 o 11:32