tomasslavicek

Android Xamarin - Contacts, Cursors, ContentResolver

Jun 21st, 2014
548
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 25.29 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using Android.App;
  5. using Android.Content;
  6. using Android.Content.Res;
  7. using Android.Database;
  8. using Android.OS;
  9. using Android.Provider;
  10. using EasyPhone.AndroidHelpers;
  11. using Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Content;
  13. using Microsoft.Xna.Framework.Graphics;
  14. using SeniorLauncher.Helpers;
  15. using Uri = Android.Net.Uri;
  16. using Phone = Android.Provider.ContactsContract.CommonDataKinds.Phone;
  17. using StructuredName = Android.Provider.ContactsContract.CommonDataKinds.StructuredName;
  18.  
  19. namespace EasyPhone.DataLayer
  20. {
  21.     /// <summary>
  22.     /// Třída pro získání kontaktů ze zařízení (jméno, Id, telefonní číslo...)
  23.     /// - jednotlivé metody jsou interně locked, využívají lokální cachování na vazvu Id -> číslo
  24.     ///   - cachování: viz parciální třída ContactsAdapter_StorageCache
  25.     /// </summary>
  26.     public partial class ContactsAdapter
  27.     {
  28.         public List<Contact> ContactList = null;
  29.         public bool NumbersFilled = false;
  30.  
  31.         Activity activity;
  32.  
  33.         object lockContactNames = new object();
  34.         object lockFillNumbers = new object();
  35.         object lockGetNumberByID = new object();
  36.         object lockLoadContactName = new object();
  37.         object lockGetFullPhoto = new object();
  38.  
  39.         public ContactsAdapter(Activity activity)
  40.         {
  41.             this.activity = activity;
  42.         }
  43.        
  44.         /// <summary>
  45.         /// Naplní pole jmen kontaktů z telefonu
  46.         /// - pouze jména, ne čísla, viz FillNumbers
  47.         /// </summary>
  48.         public void FillContactsFromPhone()
  49.         {
  50.             lock (lockContactNames)
  51.             {
  52.                 FillContacts_Locked();
  53.             }
  54.         }
  55.         private void FillContacts_Locked()
  56.         {
  57.             // Upraveno podle: http://stackoverflow.com/questions/7803633/how-to-get-android-contact-list-data-on-my-seperate-listview-in-android-2-1
  58.             // - pouze lokální kontakty: http://stackoverflow.com/questions/12932111/how-to-prevent-gmail-contacts-in-contentresolver-query-in-android
  59.             var uri = ContactsContract.Contacts.ContentUri;
  60.  
  61.             string[] projection = {
  62.                 ContactsContract.Contacts.InterfaceConsts.Id,
  63.                 ContactsContract.Contacts.InterfaceConsts.DisplayName,
  64.                 ContactsContract.Contacts.InterfaceConsts.PhotoId,
  65.                 ContactsContract.Contacts.InterfaceConsts.HasPhoneNumber
  66.             };
  67.             string selection = ContactsContract.Contacts.InterfaceConsts.InVisibleGroup + "=1";
  68.             selection += " AND " + ContactsContract.Contacts.InterfaceConsts.HasPhoneNumber + "=1";
  69.  
  70.             ICursor cursor = null;
  71.             try
  72.             {
  73.                 cursor = Game.Activity.ContentResolver.Query(uri, projection, selection, null, null);
  74.                 if (cursor == null)
  75.                     return;
  76.  
  77.                 ContactList = new List<Contact>();
  78.  
  79.                 if (cursor.MoveToFirst())
  80.                 {
  81.                     do
  82.                     {
  83.                         // Načítá pouze viditelné kontakty s telefonním číslem
  84.                         ContactList.Add(new Contact
  85.                         {
  86.                             Id = cursor.GetLong(cursor.GetColumnIndex(projection[0])),
  87.                             DisplayName = cursor.GetString(cursor.GetColumnIndex(projection[1])),
  88.                             PhotoId = cursor.GetString(cursor.GetColumnIndex(projection[2]))
  89.                         });
  90.  
  91.                     } while (cursor.MoveToNext());
  92.                 }
  93.             }
  94.             catch (Exception e)
  95.             {
  96.                 ExceptionLogger.LogException(e, false, false);
  97.             }
  98.             finally
  99.             {
  100.                 // Na konci uzavře cursor
  101.                 if (cursor != null)
  102.                     cursor.Close();
  103.             }
  104.  
  105.             // Setřídí seznam kontaktů podle jména...
  106.             ContactList.Sort();
  107.             NumbersFilled = false;
  108.         }
  109.  
  110.         /// <summary>
  111.         /// Ke každému kontaktu v ContactList načte i jeho číslo (podle ID)
  112.         /// - hodí se nám pro MessagesAdapter
  113.         /// - při načítání jenom seznamu kontaktů je to zbytečné volat! (pomalé?)
  114.         /// - cachuje si hodnoty, aby to příště bylo rychlejší :)
  115.         /// </summary>
  116.         public void FillNumbers()
  117.         {
  118.             lock (lockFillNumbers)
  119.             {
  120.                 try
  121.                 {
  122.                     FillNumbers_Locked();
  123.                 }
  124.                 catch (Exception e)
  125.                 {
  126.                     ExceptionLogger.LogException(e, false, false);
  127.                 }
  128.             }
  129.         }
  130.         private void FillNumbers_Locked()
  131.         {
  132.             // Je potřeba aktualizovat tuhle cache, když přidáváme nějaké nové číslo / měníme ho!
  133.             bool save = false;
  134.             if (cachedNumbers.Count == 0)
  135.             {
  136.                 // Načte hodnoty z Isolated Storage (je to rychlejší, než přes Cursory z Android API)
  137.                 // - načtené hodnoty rovnou uloží (cache se dále aktualizuje jen přes ActualizeCacheValue, AddCache, RemoveCache...)
  138.                 LoadNumbersFromStorage();
  139.                 save = true;
  140.             }
  141.  
  142.             for (int i = 0; i < ContactList.Count; i++)
  143.             {
  144.                 var c = ContactList[i];
  145.                 if (cachedNumbers.ContainsKey(c.Id))
  146.                     c.Number = cachedNumbers[c.Id];
  147.                 else
  148.                 {
  149.                     try
  150.                     {
  151.                         // Mohlo zde opět padat, že CursorWindows nebylo vytvořeno
  152.                         // - stává se, když se 2x znovu dotazuji na stejné číslo kontaktu?
  153.                         //   tohle cachování by to mělo snad řešit... Kdyžtak opravit!
  154.                         // - v API Androidu 2.3 se musí načítat každé číslo kontaktu zvlášť, nejde to už v FillNumbers...
  155.                         // - tohle je ale navržené OK, pokud to náhodou načetlo "", příště už to načte správně
  156.                         c.Number = GetNumberByID(c.Id);
  157.                     } catch { }
  158.  
  159.                     if (c.Number == null)
  160.                         c.Number = "";
  161.  
  162.                     if (c.Number != "")
  163.                         cachedNumbers.Add(c.Id, c.Number);
  164.                 }
  165.             }
  166.             if (save)
  167.                 SaveNumbersToStorage();
  168.  
  169.             NumbersFilled = true;
  170.         }
  171.        
  172.         /// <summary>
  173.         /// Vrátí telefonní číslo kontaktu podle jeho ID (nastavuje jako parametr kontaktu v ContactsList)
  174.         /// - voláno z FillNumbers
  175.         /// </summary>
  176.         public string GetNumberByID(long Id)
  177.         {
  178.             lock (lockGetNumberByID)
  179.             {
  180.                 return GetNumberByID_Locked(Id);
  181.             }
  182.         }
  183.         private string GetNumberByID_Locked(long Id)
  184.         {
  185.             // Načte od daného kontaktu 1 číslo (otevře a zavře si vlastní kurzor)
  186.             var uri = Phone.ContentUri;
  187.             String where = Phone.InterfaceConsts.ContactId + " = ?";
  188.             String[] selectionArgs = { Id.ToString(CultureInfo.InvariantCulture) };
  189.            
  190.             ICursor cursor = null;
  191.             string loadedPhone = "";
  192.  
  193.             try
  194.             {
  195.                 cursor = Game.Activity.ContentResolver.Query(uri, null, where, selectionArgs, null);
  196.                 if (cursor == null)
  197.                     return cachedNumbers.ContainsKey(Id) ? cachedNumbers[Id] : "";
  198.                
  199.                 if (cursor.MoveToFirst())
  200.                 {
  201.                     // OK, kurzor je fajn, získáme z něj to číslo (a zaktualizujeme případně cache)
  202.                     String phone = cursor.GetString(cursor.GetColumnIndex(Phone.Number));
  203.                     loadedPhone = phone ?? (cachedNumbers.ContainsKey(Id) ? cachedNumbers[Id] : "");
  204.                 }
  205.             }
  206.             catch (Exception e)
  207.             {
  208.                 ExceptionLogger.LogException(e, false, false);
  209.             }
  210.             finally
  211.             {
  212.                 // Na konci uzavře cursor
  213.                 if (cursor != null)
  214.                     cursor.Close();
  215.             }
  216.            
  217.             // Kdybychom chtěli všechna čísla daného kontaktu (viz 1. odpověď): http://stackoverflow.com/questions/9644704/how-to-get-specific-contact-number-by-using-contact-id
  218.             return loadedPhone;
  219.         }
  220.  
  221.         /// <summary>
  222.         /// Podle ID vrátí číslo kontaktu ze seznamu
  223.         /// - pokud seznam zatím není načtený, načte ho
  224.         /// </summary>
  225.         public Contact ReturnContactByID(long contactID)
  226.         {
  227.             // Obecně FillContacts a FillNumbers není voláno pokaždé!
  228.             // - např. u výpisu hovorů by se volalo na každý kontakt...
  229.             // - ale můžeme si to vždy zavolat sami (např. při otevření obrazovky výpisu hovorů)
  230.             if (ContactList == null)
  231.                 FillContactsFromPhone();
  232.             if (!NumbersFilled)
  233.                 FillNumbers();
  234.  
  235.             lock (lockContactNames)
  236.             {
  237.                 // Vrátí objekt kontaktu podle daného ID (ten stav null nastane jen tehdy, když tam neexistuje)
  238.                 if (ContactList == null)
  239.                     return new Contact() { Id = contactID, InContactList = false };
  240.  
  241.                 for (int i = 0; i < ContactList.Count; i++)
  242.                     if (ContactList[i].Id == contactID)
  243.                         return ContactList[i];
  244.             }
  245.             return new Contact() { Id = contactID, InContactList = false };
  246.         }
  247.        
  248.         /// <summary>
  249.         /// Vrátí ID kontaktu a "display name" pro dané telefonní číslo
  250.         /// - číslo může být "podobné" (tj. zde se otestuje na mezery, chybějící předvolbu apod.)
  251.         /// - využití: SMS zprávy, nebo nepřijaté hovory - načte k danému číslu jméno
  252.         /// - voláno z MessagesAdapter a CallListAdapter.FillList - asynchronně!
  253.         ///   - ale asynchronnost je pořešena o úroveň výš (aby si nemohl zapisovat do jednoho pole z víc míst)
  254.         /// - přeci jen to tu znovu lockujeme
  255.         /// </summary>
  256.         public void LoadContactNameBySimilarNumber(string contactNumber, out string displayName, out long contactID)
  257.         {
  258.             if (ContactList == null)
  259.                 FillContactsFromPhone();
  260.             if (!NumbersFilled)
  261.                 FillNumbers();
  262.  
  263.             lock (lockLoadContactName)
  264.             {
  265.                 try
  266.                 {
  267.                     LoadContactNameBySimilarNumber_Locked(contactNumber, out displayName, out contactID);
  268.                 }
  269.                 catch (Exception e)
  270.                 {
  271.                     ExceptionLogger.LogException(e, false, false);
  272.                     displayName = "";
  273.                     contactID = 0;
  274.                 }
  275.             }
  276.         }
  277.         private void LoadContactNameBySimilarNumber_Locked(string contactNumber, out string displayName, out long contactID)
  278.         {
  279.             // Vyhledá Id kontaktu + jeho jméno, podle "podobného čísla" (pro matchování v SMS)
  280.             displayName = "";
  281.             contactID = -1;
  282.  
  283.             if (ContactList == null)
  284.                 return;
  285.  
  286.             for (int i = 0; i < ContactList.Count; i++)
  287.             {
  288.                 var c = ContactList[i];
  289.                 if (Operations.IsSimilarNumber(c.Number, contactNumber))
  290.                 {
  291.                     displayName = c.DisplayName;
  292.                     contactID = c.Id;
  293.                     break;
  294.                 }
  295.             }
  296.             if (displayName == "")
  297.             {
  298.                 displayName = contactNumber; // Pro ty, co nejsou v telefonním seznamu
  299.                 contactID = -1;
  300.             }
  301.         }
  302.  
  303.         /// <summary>
  304.         /// Vytáhne si fotku kontaktu z contact URI (pokud existuje)
  305.         /// - předává se rovnou odkaz na texturu, na ni se případně udělá dispose, pokud už tam něco je!
  306.         /// - vrací null, pokud fotka neexistuje
  307.         /// - neděje se zde cachování textury, je nutné tuhle metodu zavolat vždy z
  308.         ///   LoadContent a RefreshScreenGraphics (z dané obrazovky, kde je takový obrázek)
  309.         /// </summary>
  310.         public void GetFullPhotoOfContact(Contact contact, GraphicsDevice device, ContentManager content, ref Texture2D texture)
  311.         {
  312.             lock (lockGetFullPhoto)
  313.             {
  314.                 GetFullPhotoOfContact_Locked(contact, device, content, ref texture);
  315.             }
  316.         }
  317.         private void GetFullPhotoOfContact_Locked(Contact contact, GraphicsDevice device, ContentManager content, ref Texture2D texture)
  318.         {
  319.             if (device == null || content == null)
  320.             {
  321.                 texture = null;
  322.                 return;
  323.             }
  324.             if (string.IsNullOrEmpty(contact.PhotoId))
  325.             {
  326.                 texture = null;
  327.                 return;
  328.             }
  329.  
  330.             // Načte velkou fotku kontaktu
  331.             if (((int) Build.VERSION.SdkInt) >= 14)
  332.             {
  333.                 // Na Androidu 14+ použije tu verzi z PDA projektu
  334.                 try
  335.                 {
  336.                     Uri cUri = Uri.WithAppendedPath(ContactsContract.Contacts.ContentUri, Convert.ToString(contact.Id));
  337.  
  338.                     using (var inStream = ContactsContract.Contacts.OpenContactPhotoInputStream(
  339.                             Game.Activity.ContentResolver, cUri, true))
  340.                     {
  341.                         Texture2D mgTexture = Texture2D.FromStream(device, inStream);
  342.                         texture = mgTexture;
  343.                         return;
  344.                     }
  345.                 }
  346.                 catch (Exception e)
  347.                 {
  348.                     // Zaloguje soft exception...
  349.                     ExceptionLogger.LogException(e, false, true);
  350.                 }
  351.                 texture = null;
  352.             }
  353.             else
  354.             {
  355.                 // Starší Androidy:
  356.                 // - musíme trochu přes hack (Xamarin nemá potřebnou konstantu, API je už deprecated)
  357.                 // http://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo.html
  358.                 var contactUri = ContentUris.WithAppendedId(ContactsContract.Contacts.ContentUri, contact.Id);
  359.                 var contactPhotoUri = Uri.WithAppendedPath(contactUri, "display_photo");
  360.  
  361.                 AssetFileDescriptor fd = null;
  362.                 try
  363.                 {
  364.                     fd = Game.Activity.ContentResolver.OpenAssetFileDescriptor(contactPhotoUri, "r");
  365.                     using (var inStream = fd.CreateInputStream())
  366.                     {
  367.                         // Načte texturu ze streamu z daného Content URI, vytvoří MonoGame texturu...
  368.                         // - obrázek je velký 480x480 px, super :)
  369.                         // - není zde cachování textury, metoda se musí volat vždy z LoadContent a RefreshScreenGraphics
  370.                         Texture2D mgTexture = Texture2D.FromStream(device, inStream);
  371.                         texture = mgTexture;
  372.                         return;
  373.                     }
  374.                 }
  375.                 catch (Exception e)
  376.                 {
  377.                     // Zaloguje soft exception...
  378.                     ExceptionLogger.LogException(e, false, true);
  379.                 }
  380.                 finally
  381.                 {
  382.                     if (fd != null)
  383.                         fd.Close();
  384.                 }
  385.                 texture = null;
  386.             }
  387.  
  388.         }
  389.        
  390.         /// <summary>
  391.         /// Přidá nový kontakt do telefonu, vrací přímo jako objekt kontaktu (aby se mohla zobrazit správná obrazovka)
  392.         /// - automaticky zaktualizuje pole ContactsList, i cache Id/číslo
  393.         /// </summary>
  394.         public Contact AddNewContact(string number, string displayName)
  395.         {
  396.             try
  397.             {
  398.                 // Via http://wptrafficanalyzer.in/blog/adding-contacts-programatically-using-contacts-provider-in-android-example/
  399.                 var ops = new List<ContentProviderOperation>();
  400.                 int rawContactID = ops.Count;
  401.  
  402.                 // Adding insert operation to operations list
  403.                 // to insert a new raw contact in the table ContactsContract.RawContacts
  404.                 ops.Add(ContentProviderOperation.NewInsert(ContactsContract.RawContacts.ContentUri)
  405.                         .WithValue(ContactsContract.RawContacts.InterfaceConsts.AccountType, null)
  406.                         .WithValue(ContactsContract.RawContacts.InterfaceConsts.AccountName, null)
  407.                         .Build());
  408.  
  409.                 // Adding insert operation to operations list
  410.                 // to insert display name in the table ContactsContract.Data
  411.                 ops.Add(ContentProviderOperation.NewInsert(ContactsContract.Data.ContentUri)
  412.                         .WithValueBackReference(ContactsContract.Data.InterfaceConsts.RawContactId, rawContactID)
  413.                         .WithValue(ContactsContract.Data.InterfaceConsts.Mimetype, StructuredName.ContentItemType)
  414.                         .WithValue(StructuredName.DisplayName, displayName)
  415.                         .Build());
  416.  
  417.                 // Adding insert operation to operations list
  418.                 // to insert Mobile Number in the table ContactsContract.Data
  419.                 ops.Add(ContentProviderOperation.NewInsert(ContactsContract.Data.ContentUri)
  420.                         .WithValueBackReference(ContactsContract.Data.InterfaceConsts.RawContactId, rawContactID)
  421.                         .WithValue(ContactsContract.Data.InterfaceConsts.Mimetype, Phone.ContentItemType)
  422.                         .WithValue(Phone.Number, number)
  423.                         .WithValue(Phone.InterfaceConsts.Type, 2) //2 = CommonDataKinds.Phone.TYPE_MOBILE
  424.                         .Build());
  425.            
  426.                 // Executing all the insert operations as a single database transaction
  427.                 var contentResolver = Game.Activity.ContentResolver;
  428.                 contentResolver.ApplyBatch(ContactsContract.Authority, ops);
  429.  
  430.                 Operations.ShowToast(Engine.Lang.Get("new_contact_added") + ": " + displayName);
  431.             }
  432.             catch (Exception e)
  433.             {
  434.                 Operations.ShowToast(Engine.Lang.Get("cannot_add_contact"));
  435.                 ExceptionLogger.LogException(e, false, false);
  436.             }
  437.  
  438.             // Kontakt už je uložený v seznamu
  439.             // - podle jména a čísla načteme aktuální ID
  440.             FillContactsFromPhone();
  441.             FillNumbers();
  442.  
  443.             //...vymazání bufferů obrazovek + přesměrování dál se děje v té metodě, co tohle volá (PressedGreenOKButton)
  444.             Contact c = GetContactByNameAndNumber(displayName, number);
  445.             if (c != null)
  446.                 AddCacheValue(c.Id, number);
  447.             return c;
  448.         }
  449.  
  450.         private Contact GetContactByNameAndNumber(string displayName, string number)
  451.         {
  452.             // Projde si načtený seznam kontaktů, vrátí objekt kontaktu podle jména / čísla
  453.             lock (lockContactNames)
  454.             {
  455.                 for (int i = 0; i < ContactList.Count; i++)
  456.                 {
  457.                     if (ContactList[i].DisplayName == displayName &&
  458.                         ContactList[i].Number == number)
  459.                     {
  460.                         return ContactList[i];
  461.                     }
  462.                 }
  463.             }
  464.             return null;
  465.         }
  466.        
  467.         /// <summary>
  468.         /// Nastaví danému kontaktu nové jméno a číslo, zaktualizuje ho v telefonu
  469.         /// - obnoví i potřebné buffery (cache)
  470.         /// </summary>
  471.         public Contact UpdateContact(Contact contact, string number, string displayName)
  472.         {
  473.             // Zaktualizuje reálně kontakt v telefonu:
  474.             // http://stackoverflow.com/questions/8490123/how-to-update-existing-contact?rq=1
  475.             try
  476.             {
  477.                 var ops = new List<ContentProviderOperation>();
  478.                 int rawContactID = GetRawContactID(contact);
  479.                 if (rawContactID == -1)
  480.                 {
  481.                     Operations.ShowToast(Engine.Lang.Get("cannot_update_contact"));
  482.                     return contact;
  483.                 }
  484.  
  485.                 // Jméno a číslo...
  486.                 var contentResolver = Game.Activity.ContentResolver;
  487.                 String where = ContactsContract.Data.InterfaceConsts.ContactId + " = ? AND "
  488.                     + ContactsContract.Data.InterfaceConsts.Mimetype + " = ?";
  489.                 String[] nameParams = { Convert.ToString(contact.Id), StructuredName.ContentItemType };
  490.                 String[] numberParams = { Convert.ToString(contact.Id), Phone.ContentItemType };
  491.  
  492.                 ops.Add(ContentProviderOperation.NewUpdate(ContactsContract.Data.ContentUri)
  493.                           .WithSelection(where, nameParams)
  494.                           .WithValue(StructuredName.DisplayName, displayName)
  495.                           .Build());
  496.                 ops.Add(ContentProviderOperation.NewUpdate(ContactsContract.Data.ContentUri)
  497.                           .WithSelection(where,numberParams)
  498.                           .WithValue(Phone.Number, number)
  499.                           .Build());
  500.  
  501.                 // Executing all the insert operations as a single database transaction
  502.                 contentResolver.ApplyBatch(ContactsContract.Authority, ops);
  503.  
  504.                 Operations.ShowToast(Engine.Lang.Get("new_contact_edited") + ": " + displayName);
  505.             }
  506.             catch (Exception e)
  507.             {
  508.                 Operations.ShowToast(Engine.Lang.Get("cannot_update_contact"));
  509.                 ExceptionLogger.LogException(e, false, false);
  510.             }
  511.  
  512.             // Zaktualizuje cache
  513.             ActualizeCacheValue(contact.Id, number);
  514.             contact.Number = number;
  515.             contact.DisplayName = displayName;
  516.  
  517.             // A znovu načte aktuální data...
  518.             FillContactsFromPhone();
  519.             return contact;
  520.         }
  521.  
  522.         private int GetRawContactID(Contact contact)
  523.         {
  524.             // Načte "raw" ID kontaktu (to, podle kterého se přidávalo do seznamu)
  525.             // - potřebujeme ho pro editaci (v UpdateContact)
  526.             int outValue = -1;
  527.             ICursor cursor = null;
  528.             try
  529.             {
  530.                 cursor = Game.Activity.ContentResolver.Query(
  531.                     ContactsContract.RawContacts.ContentUri,
  532.                     new[] { ContactsContract.RawContacts.InterfaceConsts.Id },
  533.                     ContactsContract.RawContacts.InterfaceConsts.ContactId + "=?",
  534.                     new[] { Convert.ToString(contact.Id)}, null);
  535.  
  536.                 if (cursor != null)
  537.                     if (cursor.MoveToFirst())
  538.                         outValue = Convert.ToInt32(cursor.GetLong(0));
  539.             }
  540.             catch (Exception e)
  541.             {
  542.                 ExceptionLogger.LogException(e, false, false);
  543.             }
  544.             finally
  545.             {
  546.                 if (cursor != null)
  547.                     cursor.Close();
  548.             }
  549.             return outValue;
  550.         }
  551.  
  552.         /// <summary>
  553.         /// Smaže daný kontakt... (3. metoda z ContactDetailScreen)
  554.         /// </summary>
  555.         public void RemoveContact(Contact contact)
  556.         {
  557.             // Najde kontakt podle ID, smaže ho, uzavře zpátky cursor
  558.             ICursor cursor = null;
  559.             try
  560.             {
  561.                 var cr = Game.Activity.ContentResolver;
  562.                 cursor = cr.Query(ContactsContract.Contacts.ContentUri,
  563.                     null, ContactsContract.Contacts.InterfaceConsts.Id + "=" + contact.Id, null, null);
  564.                 if (cursor == null)
  565.                 {
  566.                     Operations.ShowToast(Engine.Lang.Get("cannot_delete_contact"));
  567.                     return;
  568.                 }
  569.                
  570.                 // Smaže pouze první, i kdyby jich tam bylo víc...
  571.                 if (cursor.MoveToNext())
  572.                 {
  573.                     String lookupKey = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.LookupKey));
  574.                     Uri uri = Uri.WithAppendedPath(
  575.                         ContactsContract.Contacts.ContentLookupUri, lookupKey);
  576.                     cr.Delete(uri, ContactsContract.Contacts.InterfaceConsts.Id + "=" + contact.Id, null);
  577.  
  578.                     Operations.ShowToast(Engine.Lang.Get("contact_deleted") + ": " + contact.DisplayName);
  579.                 }
  580.             }
  581.             catch (Exception e)
  582.             {
  583.                 Operations.ShowToast(Engine.Lang.Get("cannot_delete_contact"));
  584.                 ExceptionLogger.LogException(e, false, false);
  585.             }
  586.             finally
  587.             {
  588.                 if (cursor != null)
  589.                     cursor.Close();
  590.             }
  591.  
  592.             // A znovu načte aktuální data...
  593.             RemoveCacheValue(contact.Id);
  594.             FillContactsFromPhone();
  595.         }
  596.     }
  597.    
  598. }
Advertisement
Add Comment
Please, Sign In to add comment