Kontakty
Omówienie: http://saigeethamn.blogspot.in/2011/05/contacts-api-20-and-above-android.html
All data related to a contact is stored in this generic data table with each row telling
what is the data it stores through its MIME type. So we could have a Phone.CONTENT_ITEM_TYPE
as the MIME type of the data row, it contains Phone data. Similarly, if we have
Email.CONTENT_ITEM_TYPE as the row’s MIME type, then it stores email data. Like this lot of
data rows are associated with a single Raw Contact
Więcej szczegółów: http://www.higherpass.com/Android/Tutorials/Working-With-Android-Contacts/
-----------------------------------------
Lista kontaktów
1. Tworzymy projekt aplikacji Android App (Xamarin) o nazwie Kontakty.
Wybieramy szablon Blank App i Android 5.0 (Lollipop).
Będziemy używać Contacts API 2.0.
2. Przechodzimy do pliku Resources/layout/activity_main.xml
3. Następnie modyfikujemy plik res/values/strings.xml
Kontakty
Settings
Kontakty <--- Dodane
Settings
Kontakty
4. Do katalogu głównego dodajemy plik klasy Kontakt.cs
zawierający klasę z na razie jedna statyczna metodą:
using System;
using System.Collections.Generic;
using Android.Content;
using Android.Database;
using Android.Provider;
namespace Kontakty
{
class Kontakt
{
//pozniej bedziemy czytali liste rekordów z większą ilością szczegółów
public static List listaNazwWszystkichKontaktow(ContentResolver contentResolver)
{
List lista = new List();
ICursor cursor = contentResolver.Query(ContactsContract.Contacts.ContentUri, null, null, null, null);
if (cursor.Count > 0)
{
while (cursor.MoveToNext())
{
string nazwa = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.DisplayName));
string id = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.Id));
lista.Add("[" + id + "] " + nazwa);
}
}
else
{
lista = null;
}
cursor.Close();
return lista;
}
}
}
5. Mając taką metodę możemy zapełnić kontrolkę ListView łańcuchami z nazwami kontaktów.
W tym celu w klasie MainActivity:
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using System.Collections.Generic;
using Android.Content.PM;
namespace Kontakty
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
private ListView listView;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
showContacts();
}
private void showContacts()
{
//dane dla listy
List lista = Kontakt.ListaNazwWszystkichKontaktow(this.ContentResolver);
if (lista == null)
{
TextView naglowek = FindViewById(Resource.Id.naglowek);
naglowek.Text = "Brak zdefiniowanych kontaktów";
}
ArrayAdapter adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, lista);
// kontrolka
listView = FindViewById(Resource.Id.listView);
listView.Adapter = adapter;
}
}
}
6. Uruchomienie aplikacji skończy się błędem. Aby odczytać listę kontaktów, aplikacja musi mieć
odpowiednie uprawnienia. W ustawieniach należy dodać uprawnienie READ_CONTACTS (przez Properties/Android Manifest).
Lista kontaktów może być pusta. Można utworzyć przykładowe kontakty korzystając z interfejsu
androida, ale można też stworzyć kontakty z poziomu aplikacji (poniżej).
7. Od wersji Marshmallow należy pobrać uprawnienia dodatkowo w runtime:
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using System.Collections.Generic;
using Android.Content.PM;
namespace Kontakty
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
private ListView listView;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M && this.CheckSelfPermission(Android.Manifest.Permission.ReadContacts) != Permission.Granted)
{
this.RequestPermissions(new string[] { Android.Manifest.Permission.ReadContacts }, PERMISSIONS_REQUEST_READ_CONTACTS);
//After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
}
else
{
// Android version is lesser than 6.0 or the permission is already granted.
showContacts();
}
}
private void showContacts()
{
//dane dla listy
List lista = Kontakt.ListaNazwWszystkichKontaktow(this.ContentResolver);
if (lista == null)
{
TextView naglowek = FindViewById(Resource.Id.naglowek);
naglowek.Text = "Brak zdefiniowanych kontaktów";
}
ArrayAdapter adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, lista);
// kontrolka
listView = FindViewById(Resource.Id.listView);
listView.Adapter = adapter;
}
private const int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS)
{
if (grantResults[0] == Permission.Granted)
{
// Permission is granted
showContacts();
}
else
{
Toast.MakeText(this, "Nie można wyświetlać kontaktów do momentu udzielenia zgody", ToastLength.Short).Show();
}
}
}
}
}
---------------
Zapis nowego kontaktu do bazy danych i usunięcie wszystkich istniejących
8. Rozbudujmy klasę Kontakt z pliku Kontakt.cs czyniąc z niej klasę encji (nadal niekompletną):
using System.Collections.Generic;
using Android.Content;
using Android.Database;
using Android.Net;
using Android.Provider;
namespace Kontakty
{
class Kontakt
{
public string NazwaWyswietlana;
public string TelefonKomorkowy;
public string TelefonDomowy;
public string TelefonWPracy;
public string EmailWPracy;
public string Firma;
public string Tytul;
//mozna uzupelnic m.in. o zdjecie
public Kontakt(
string nazwaWyswietlana,
string telefonKomorkowy,
string telefonDomowy,
string telefonWPracy,
string emailWPracy,
string firma,
string tytul)
{
this.NazwaWyswietlana = nazwaWyswietlana;
this.TelefonKomorkowy = telefonKomorkowy;
this.TelefonDomowy = telefonDomowy;
this.TelefonWPracy = telefonWPracy;
this.EmailWPracy = emailWPracy;
this.Firma = firma;
this.Tytul = tytul;
}
public static List ListaNazwWszystkichKontaktow(ContentResolver contentResolver)
{
List lista = new List();
ICursor cursor = contentResolver.Query(ContactsContract.Contacts.ContentUri, null, null, null, null);
if (cursor.Count > 0)
{
while (cursor.MoveToNext())
{
string nazwa = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.DisplayName));
string id = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.Id));
lista.Add("[" + id + "] " + nazwa);
}
}
else
{
lista = null;
}
cursor.Close();
return lista;
}
public static void UsuńWszystkieKontakty(ContentResolver contentResolver)
{
ICursor cursor = contentResolver.Query(ContactsContract.Contacts.ContentUri, null, null, null, null);
while (cursor.MoveToNext())
{
string klucz = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.LookupKey));
Uri uri = Uri.WithAppendedPath(ContactsContract.Contacts.ContentLookupUri, klucz);
contentResolver.Delete(uri, null, null);
}
cursor.Close();
}
//Zrodlo: http://stackoverflow.com/questions/4744187/how-to-add-new-contacts-in-android
private static void dodajNowyKontaktDoBazy(ContentResolver contentResolver, Kontakt kontakt)
{
List dodawanyKontakt = new List();
dodawanyKontakt.Add(ContentProviderOperation.NewInsert(
ContactsContract.RawContacts.ContentUri)
.WithValue(ContactsContract.RawContacts.InterfaceConsts.AccountType, null)
.WithValue(ContactsContract.RawContacts.InterfaceConsts.AccountName, null)
.Build());
if (kontakt.NazwaWyswietlana != null)
{
dodawanyKontakt.Add(ContentProviderOperation.NewInsert(ContactsContract.Data.ContentUri)
.WithValueBackReference(ContactsContract.Data.InterfaceConsts.RawContactId, 0)
.WithValue(ContactsContract.Data.InterfaceConsts.Mimetype, ContactsContract.CommonDataKinds.StructuredName.ContentItemType)
.WithValue(ContactsContract.CommonDataKinds.StructuredName.DisplayName, kontakt.NazwaWyswietlana)
.Build());
}
if (kontakt.TelefonKomorkowy != null)
{
dodawanyKontakt.Add(ContentProviderOperation.NewInsert(ContactsContract.Data.ContentUri)
.WithValueBackReference(ContactsContract.Data.InterfaceConsts.RawContactId, 0)
.WithValue(ContactsContract.Data.InterfaceConsts.Mimetype, ContactsContract.CommonDataKinds.Phone.ContentItemType)
.WithValue(ContactsContract.CommonDataKinds.Phone.Number, kontakt.TelefonKomorkowy)
//.WithValue(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Phone.GetTypeLabelResource(PhoneDataKind.Mobile))
.WithValue(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.TypeCustom)
.WithValue(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Label, "Mobile")
.Build());
}
if (kontakt.TelefonDomowy != null)
{
dodawanyKontakt.Add(ContentProviderOperation.NewInsert(ContactsContract.Data.ContentUri)
.WithValueBackReference(ContactsContract.Data.InterfaceConsts.RawContactId, 0)
.WithValue(ContactsContract.Data.InterfaceConsts.Mimetype, ContactsContract.CommonDataKinds.Phone.ContentItemType)
.WithValue(ContactsContract.CommonDataKinds.Phone.Number, kontakt.TelefonDomowy)
//.WithValue(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Phone.GetTypeLabelResource(PhoneDataKind.Home))
.WithValue(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.TypeCustom)
.WithValue(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Label, "Home")
.Build());
}
if (kontakt.TelefonWPracy != null)
{
dodawanyKontakt.Add(ContentProviderOperation.NewInsert(ContactsContract.Data.ContentUri)
.WithValueBackReference(ContactsContract.Data.InterfaceConsts.RawContactId, 0)
.WithValue(ContactsContract.Data.InterfaceConsts.Mimetype, ContactsContract.CommonDataKinds.Phone.ContentItemType)
.WithValue(ContactsContract.CommonDataKinds.Phone.Number, kontakt.TelefonWPracy)
//.WithValue(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Phone.GetTypeLabelResource(PhoneDataKind.Work))
.WithValue(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.TypeCustom)
.WithValue(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Label, "Work")
.Build());
}
if (kontakt.EmailWPracy != null)
{
dodawanyKontakt.Add(ContentProviderOperation.NewInsert(ContactsContract.Data.ContentUri)
.WithValueBackReference(ContactsContract.Data.InterfaceConsts.RawContactId, 0)
.WithValue(ContactsContract.Data.InterfaceConsts.Mimetype, ContactsContract.CommonDataKinds.Email.ContentItemType)
.WithValue(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Data, kontakt.EmailWPracy)
//.WithValue(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Email.GetTypeLabelResource(EmailDataKind.Work))
.WithValue(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.TypeCustom)
.WithValue(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Label, "Work")
.Build());
}
if (string.IsNullOrEmpty(kontakt.Firma) && string.IsNullOrEmpty(kontakt.Tytul))
{
dodawanyKontakt.Add(ContentProviderOperation.NewInsert(ContactsContract.Data.ContentUri)
.WithValueBackReference(ContactsContract.Data.InterfaceConsts.RawContactId, 0)
.WithValue(ContactsContract.Data.InterfaceConsts.Mimetype, ContactsContract.CommonDataKinds.Organization.ContentItemType)
.WithValue(ContactsContract.CommonDataKinds.Organization.Company, kontakt.Firma)
//.WithValue(ContactsContract.CommonDataKinds.Organization.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Organization.GetTypeLabelResource(OrganizationDataKind.Work))
.WithValue(ContactsContract.CommonDataKinds.Organization.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.TypeCustom)
.WithValue(ContactsContract.CommonDataKinds.Organization.InterfaceConsts.Label, "Work")
.WithValue(ContactsContract.CommonDataKinds.Organization.Title, kontakt.Tytul)
//.WithValue(ContactsContract.CommonDataKinds.Organization.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Organization.GetTypeLabelResource(OrganizationDataKind.Work))
.WithValue(ContactsContract.CommonDataKinds.Organization.InterfaceConsts.Type, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.TypeCustom)
.WithValue(ContactsContract.CommonDataKinds.Organization.InterfaceConsts.Label, "Work")
.Build());
}
//prosba do dostawcy kontaktaktow o utworzenie nowego kontaktu
//try
//{
contentResolver.ApplyBatch(ContactsContract.Authority, dodawanyKontakt);
//return true;
//}
//catch (Exception e)
//{
//e.printStackTrace();
//return false;
//}
}
public void Zapisz(ContentResolver contentResolver)
{
dodajNowyKontaktDoBazy(contentResolver, this);
}
}
}
9. W klasie aktywności dodajemy kod usuwający wszystkie istniejące kontakty i dodające dwa
nowe oraz pobierający w runtime uprawnienie do zmiany kontaktów:
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using System.Collections.Generic;
using Android.Content.PM;
namespace Kontakty
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
private ListView listView;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M && this.CheckSelfPermission(Android.Manifest.Permission.WriteContacts) != Permission.Granted)
{
this.RequestPermissions(new string[] { Android.Manifest.Permission.WriteContacts }, PERMISSIONS_REQUEST_WRITE_CONTACTS);
}
else
{
addContacts();
}
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M && this.CheckSelfPermission(Android.Manifest.Permission.ReadContacts) != Permission.Granted)
{
this.RequestPermissions(new string[] { Android.Manifest.Permission.ReadContacts }, PERMISSIONS_REQUEST_READ_CONTACTS);
//After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
}
else
{
// Android version is lesser than 6.0 or the permission is already granted.
showContacts();
}
}
private void addContacts()
{
Kontakt.UsuńWszystkieKontakty(ContentResolver);
try
{
new Kontakt(
"Jacek Matulewski", "+48600123456", null, "+48(56)6113310",
"jacek@fizyka.umk.pl", "UMK", "Dr").Zapisz(ContentResolver);
new Kontakt(
"Jan Kowalski", "+48600987654", "11111111", "+48(56)1111111",
"jankowalski@firma.pl", "AAAAA", null).Zapisz(ContentResolver);
}
catch (Java.Lang.Exception exc)
{
Toast.MakeText(ApplicationContext,
"Nie udało się dodać kontaktu (" + exc.Message + ")",
ToastLength.Long).Show();
}
}
private void showContacts()
{
//dane dla listy
List lista = Kontakt.ListaNazwWszystkichKontaktow(this.ContentResolver);
if (lista == null)
{
TextView naglowek = FindViewById(Resource.Id.naglowek);
naglowek.Text = "Brak zdefiniowanych kontaktów";
return;
}
ArrayAdapter adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, lista);
// kontrolka
listView = FindViewById(Resource.Id.listView);
listView.Adapter = adapter;
}
private const int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
private const int PERMISSIONS_REQUEST_WRITE_CONTACTS = 101;
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
switch(requestCode)
{
case PERMISSIONS_REQUEST_READ_CONTACTS:
if (grantResults[0] == Permission.Granted)
{
// Permission is granted
showContacts();
}
else
{
Toast.MakeText(this, "Nie można wyświetlać kontaktów do momentu udzielenia zgody", ToastLength.Short).Show();
}
break;
case PERMISSIONS_REQUEST_WRITE_CONTACTS:
if (grantResults[0] == Permission.Granted)
{
addContacts();
showContacts();
}
else
{
Toast.MakeText(this, "Nie można dodawać kontaktów do momentu udzielenia zgody", ToastLength.Short).Show();
}
break;
}
}
}
}
10. Do tego potrzebne jest uprawnienie, które dodajemy do manifestu: WRITE_CONTACTS
----------------------
Odczyt kompletnych kontaktów
11. Do klasy Kontakt dodajmy jeszcze jedną statyczną metodę pozwalającą na odczyt pełnej listy
kontaktów oraz statyczną metodę wspomagającą tworzenie instancji kontaktów na podstawie
danych z rekordu bazy danych:
namespace Kontakty
{
class Kontakt
{
...
private static Kontakt odczytajKontaktZBazyDanych(ContentResolver contentResolver, ICursor cursor)
{
string id = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.Id));
string nazwaWyświetlana = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.DisplayName));
string telefonKomórkowy = "", telefonDomowy = "", telefonWPracy = "", emailWPracy = "", firma = "", tytuł = "";
if (int.Parse(cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.HasPhoneNumber))) > 0)
{
ICursor numeryTelefonow = contentResolver.Query(ContactsContract.CommonDataKinds.Phone.ContentUri, null, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + " = " + id, null, null);
while (numeryTelefonow.MoveToNext())
{
string numer = numeryTelefonow.GetString(numeryTelefonow.GetColumnIndex(ContactsContract.CommonDataKinds.Phone.Number));
string typNumeru = numeryTelefonow.GetString(numeryTelefonow.GetColumnIndex(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Label));
switch (typNumeru)
{
case "Mobile":
telefonKomórkowy = numer;
break;
case "Home":
telefonDomowy = numer;
break;
case "Work":
telefonWPracy = numer;
break;
}
}
numeryTelefonow.Close();
}
ICursor adresyEmail = contentResolver.Query(ContactsContract.CommonDataKinds.Email.ContentUri, null, ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId + " = " + id, null, null);
while (adresyEmail.MoveToNext())
{
string adresEmail = adresyEmail.GetString(adresyEmail.GetColumnIndex(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Data));
string typAdresu = adresyEmail.GetString(adresyEmail.GetColumnIndex(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Label));
if (typAdresu == "Work")
{
emailWPracy = adresEmail;
break; //przerwanie petli while
}
}
adresyEmail.Close();
//organizacja
string where = ContactsContract.Data.InterfaceConsts.ContactId + " = ? AND " + ContactsContract.Data.InterfaceConsts.Mimetype + " = ?";
string[] whereParams = new string[]
{
id,
ContactsContract.CommonDataKinds.Organization.ContentItemType
};
ICursor organizacje = contentResolver.Query(ContactsContract.Data.ContentUri, null, where, whereParams, null);
if (organizacje.MoveToFirst())
{
firma = organizacje.GetString(organizacje.GetColumnIndex(ContactsContract.CommonDataKinds.Organization.InterfaceConsts.Data));
tytuł = organizacje.GetString(organizacje.GetColumnIndex(ContactsContract.CommonDataKinds.Organization.Title));
}
organizacje.Close();
return new Kontakt(nazwaWyświetlana, telefonKomórkowy, telefonDomowy, telefonWPracy, emailWPracy, firma, tytuł);
}
public static List ListaWszystkichKontaktow(ContentResolver contentResolver)
{
List lista = new List();
ICursor cursor = contentResolver.Query(ContactsContract.Contacts.ContentUri, null, null, null, null);
if (cursor.Count > 0)
{
while (cursor.MoveToNext())
{
Kontakt kontakt = odczytajKontaktZBazyDanych(contentResolver, cursor);
lista.Add(kontakt);
}
}
else
{
lista = null;
}
return lista;
}
public static List ListaOpisowWszystkichKontaktow(ContentResolver contentResolver)
{
List listaKontaktow = Kontakt.ListaWszystkichKontaktow(contentResolver);
List lista = new List();
foreach (Kontakt kontakt in listaKontaktow)
{
string opis =
kontakt.Tytul + " " + kontakt.NazwaWyswietlana +
"\ntel. kom.:" + kontakt.TelefonKomorkowy +
"\ne-mail:" + kontakt.EmailWPracy;
lista.Add(opis.Trim());
}
return lista;
}
}
}
12. Metoda ListaOpisowWszystkichKontaktow służy jedynie do testowania metody ListaWszystkichKontaktow.
Korzystając z tej nowej statycznej metody Kontakt.ListaOpisowWszystkichKontaktow wyświetlmy
w liście więcej informacji o kontaktach. Wystarczy podmienić metodę ListaOpisowNazwKontaktow:
public class MainActivity extends Activity
{
private void showContacts()
{
//dane dla listy
//List lista = Kontakt.ListaNazwWszystkichKontaktow(this.ContentResolver);
List lista = Kontakt.ListaOpisowWszystkichKontaktow(this.ContentResolver); <------------
if (lista == null)
{
TextView naglowek = FindViewById(Resource.Id.naglowek);
naglowek.Text = "Brak zdefiniowanych kontaktów";
return;
}
ArrayAdapter adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, lista);
// kontrolka
listView = FindViewById(Resource.Id.listView);
listView.Adapter = adapter;
}
----------------------
Użycie danych z kontaktów do inicjacji połączenia wychodzącego
13. Zaczniemy od przygotowania menu podręcznego inicjowanego dłuższym przytrzymaniem pozycji
w liście. W metodzie MainActivity.showContacts dodajemy:
private void showContacts()
{
//dane dla listy
//List lista = Kontakt.ListaNazwWszystkichKontaktow(this.ContentResolver);
List lista = Kontakt.ListaOpisowWszystkichKontaktow(this.ContentResolver);
if (lista == null)
{
TextView naglowek = FindViewById(Resource.Id.naglowek);
naglowek.Text = "Brak zdefiniowanych kontaktów";
return;
}
ArrayAdapter adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, lista);
// kontrolka
listView = FindViewById(Resource.Id.listView);
listView.Adapter = adapter;
List listaKontaktów = Kontakt.ListaWszystkichKontaktow(ContentResolver); <------------------------
listView.ItemLongClick +=
(object sender, AdapterView.ItemLongClickEventArgs e) =>
{
Kontakt kontakt = listaKontaktów[e.Position];
Android.App.AlertDialog.Builder adb = new Android.App.AlertDialog.Builder(e.Parent.Context);
adb.SetTitle(kontakt.NazwaWyswietlana);
string[] etykiety = { "Zadzwoń (tel. kom.)", "Wyślij SMS", "Napisz e-mail", "Anuluj" };
adb.SetItems(
etykiety,
(object _sender, Android.Content.DialogClickEventArgs _e) =>
{
switch (_e.Which)
{
case 0:
break;
case 1:
break;
case 2:
break;
default:
case 3:
break;
}
});
Android.App.AlertDialog ad = adb.Create();
ad.Show();
};
}
14. Wystarczy teraz tylko uzupełnić instrukcję switch case 0 o odpowiednią intencję:
[To jako zadanie do samodzielnego wykonania!!!]
switch (_e.Which)
{
case 0:
Intent i = new Intent(Intent.ActionCall);
i.SetData(Android.Net.Uri.Parse("tel:" + kontakt.TelefonKomorkowy));
//Finish();
StartActivity(i);
break;
Uwaga! Przed uruchomieniem dodajemy do manifestu uprawnienie do dzwonienia (CALL_PHONE).
W nowszych systemach (Android 8.0 Oreo) należy to uprawnienie pobrać też w runtime (na wzór uprawnień do czytania kontaktów w tym samym projekcie).
---------------------------
[Dalsze też jako zadania]
Wysyłanie SMSów
15. Można to zrobić na dwa sposoby. Albo, tak jak w przypadku inicjacji połączeń użyć systemowej
aktywności, albo skorzystać z niskopoziomowego API android.telephony:
Uwaga! Pierwsza wersja nie wymaga specjalnych uprawnień, ponieważ pojawia się okno z treścią SMS i przyciskiem do wysłania
switch (_e.Which)
{
case 0:
{
Intent i = new Intent(Intent.ActionCall);
i.SetData(Android.Net.Uri.Parse("tel:" + kontakt.TelefonKomorkowy));
//Finish();
StartActivity(i);
}
break;
case 1:
{
string tekst = "Przykładowa treść";
Intent i = new Intent(Intent.ActionSendto, Android.Net.Uri.Parse("smsto:" + kontakt.TelefonKomorkowy));
i.PutExtra("sms_body", tekst);
StartActivity(i);
}
break;
/*
//Java
SmsManager sms = SmsManager.getDefault();
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, new Intent(getBaseContext(),KontaktyActivity.class), 0);
sms.sendTextMessage(kontakt.telefonKomorkowy, null, tekst, null, null);
Toast.makeText(getBaseContext(), "Wyslanie SMSa powiodło się", Toast.LENGTH_LONG).show();
*/
W tym drugim (zakomentowanym) przypadku potrzebne jest uprawnienie:
---------------------------
Wysyłanie listów e-mail
16. W przypadku listów e-mail dwie wariacje metody (plain i z formatowaniem):
case 2:
{
string tekst = "Przykładowa treść";
Intent i = new Intent(Intent.ActionSend);
i.SetType("message/rfc822");
i.PutExtra(Intent.ExtraEmail, new string[] { kontakt.EmailWPracy }); //tu moze byc wielu odbiorcow
i.PutExtra(Intent.ExtraSubject, "Temat listu");
i.PutExtra(Intent.ExtraText, tekst);
try
{
StartActivity(Intent.CreateChooser(i, "Wyślij e-mail..."));
}
catch (Android.Content.ActivityNotFoundException)
{
Toast.MakeText(this, "Brak zainstalowanych aplikacji do wysyłania listów e-mail", ToastLength.Short).Show();
}
}
break;
/*
//Java
Intent intencja = new Intent(Intent.ACTION_SENDTO); // it's not ACTION_SEND
intencja.setType("text/plain");
intencja.putExtra(Intent.EXTRA_SUBJECT, "Temat listu");
intencja.putExtra(Intent.EXTRA_TEXT, tekst);
intencja.setData(Uri.parse("mailto:"+kontakt.emailWPracy)); // or just "mailto:" for blank
intencja.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // this will make such that when user returns to your app, your app is displayed, instead of the email app.
startActivity(intencja);
*/
}
break;