can we load deleted contacts' data from contacts content provider? - android

hello~ when we delete contacts in android, android just sets raw_contacts.deleted=1. All data of the deleted contact can be found in the table "data" by SQLiteAdmin or other tools.
I want to load these deleted contacts' data, but it doesn't work.codes are as foloowed:
private void restoreContactsData() {
Uri idUri=Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri=Uri.parse("content://"+ContactsContract.AUTHORITY+"/data");
Cursor c=cr.query(idUri, new String[]{"_id"}, "deleted=1", null, null);
StringBuilder sb=new StringBuilder();
while(c.moveToNext()){
int deletedRawContactId=c.getInt(0);
sb.append("rawId="+deletedRawContactId).append("\n\t");
Cursor dataCursor=cr.query(dataUri,
new String[]{"data1"},
"row_contact_id="+deletedRawContactId,
null,
null);
while(dataCursor.moveToNext()){
String phone=dataCursor.getString(0);
sb.append(phone).append("\n");
}
}
tv.setText(sb.toString());
}
I have tried to set the constant VISIBLE_CONTACTS_ONLY=false as parameter,but i wont' work either.
The method above can find the deleted raw_contact ids.BUT when I use these ids to query the "data" table , it return nothing.
If I pull the contacts2.db file out of emulator, I can find the data which are associated with the deleted raw_contact in the "data" table.
The question is ,whether can i restore these deleted data from contacts' contentprovider?
Thank you

Related

Android get data for contact using lookup key

I need to retrieve all data for a single contact which was chosen by a user (Action.Pick). I want to use LOOKUP KEY as suggested by developer.android.com. Can I do it by a simple query without creating Loader etc. as suggested by the documentation ?
I wrote this method for my application:
public static Cursor getContactCursorByLookUpKey(Context context,String lookUpKey)
{
ContentResolver contentResolver = context.getContentResolver();
Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI,lookUpKey);
return contentResolver.query(lookupUri,null,null,null,null);
}
To get the data simply read data from the cursor. For example :
Cursor data = ContactManager.getContactCursorByLookUpKey(ContactDetailsActivity.this,lookUpKey);
String name = data.getString(data.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String photoPath = data.getString(data.getColumnIndex(ContactsContract.Contacts.PHOTO_URI));
You can query the Contacts provider using ContentResolver directly, if you have the READ_CONTACTS permission. You will receive a cursor with multiple rows of raw contact details (phones, emails, etc.). Iterate over the cursor to read them and don't forget to close the cursor.

Getting details of edited contact back using ACTION_EDIT and startActivityForResult()

I am maintaining a list of contacts for my application. First I pick contact using ACTION_PICK with an intent. I am saving these contacts in my local database along with CONTACT_ID. Now user may choose to edit any contact to add some extra information that my app needs. I fire that edit intent with ACTION_EDIT. I have two questions here
I am saving CONTACT_ID to my database in order to use in edit intent. First question is does this id changes after edition ? because It so happens that I am unable to open contact editor for same contact again.
Second question is how can I read back all the details of this edited contact ? I am getting this back in my onActivityResult(). I have tried to use same code which i am using in case of picking but data structure returned in case of edit is different it seems.
you can get any data from contacts using a cursor like
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup._ID};
// query time
Cursor cursor = _context.getContentResolver()
.query("ContactsContract.Contacts.CONTENT_URI",
projection, null, null, null);
if(cursor != null) {
while ( cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(
ContactsContract.PhoneLookup.DISPLAY_NAME));
// do other stuff
}
}
cursor.close();
take a look at https://developer.android.com/training/contacts-provider/retrieve-details.html

How to aggregate the rawContacts using aggregationException content correclty

I'm backing up and restoring contacts, I'm able to do it, but while aggregation of rawcontacts for linked contacts(joined contacts) using ContactsContract.AggregationExceptions
If i join 3 contacts, say Contact A (master) and Contact B (linked) and C (linked)
I do the backup ,and restore,for the newly created id's with correct mapping, I'm updating the ContactsContract.AggregationExceptions.CONTENT_URI with following code:
private boolean aggregateContactLinks() {
ContentResolver cr = context.getContentResolver();
int listCount = linkList.size();
ContentValues values = new ContentValues(3);
Log.i(tag, "aggregating contacts");
for (int i=0; i<listCount; i++) {
values.put(AggregationExceptions.RAW_CONTACT_ID1,
linkList.get(i).newId1);
values.put(AggregationExceptions.RAW_CONTACT_ID2,
linkList.get(i).newId2);
values.put(AggregationExceptions.TYPE,
AggregationExceptions.TYPE_KEEP_TOGETHER);
Log.i(tag," new master id(id1) :"+linkList.get(i).newId+"\nlinkid2 :"+newId2);
Log.i(tag,
"result :"
+ cr.update(AggregationExceptions.CONTENT_URI,
values, null, null));
Log.i(tag, "\nupdated one contact");
}
values.clear();
return true;
}
output , on phone i can see the linked content but in display name of contact is c instead of a
before backup
after backup, deleting the contacts and after restore
can anyone know where exactly im going wrong,thanks in advance
If you want to tell Android contact provider that it should use the specific raw contact name for aggregated contact (not display names of linked contacts B and C but the display name of master contact A), you may use RawContactsColumn.NAME_VERIFIED. Simply set it to "1" for your master raw contact after updating aggregation exceptions.
I found this trick in the standard Contacts application's
code:
// Mark the original contact as "name verified" to make sure that the contact
// display name does not change as a result of the join
if (verifiedNameRawContactId != -1) {
Builder builder = ContentProviderOperation.newUpdate(
ContentUris.withAppendedId(RawContacts.CONTENT_URI, verifiedNameRawContactId));
builder.withValue(RawContacts.NAME_VERIFIED, 1);
operations.add(builder.build());
}
RawContactsColumn interface is protected, so you should use "name_verified" as column name. Because of the fact that RawContactsColumn isn't open, maybe you should also check if "name_verified" column exists before updating to avoid crashes.

getting notes from a single contact - android

I'm trying to get "notes" from a single contact. It added fine but retrieving it has been a problem.
String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" like'%" + sender +"%'";
String[] projection = new String[] { ContactsContract.CommonDataKinds.Note.NOTE};
Cursor c2 = getContentResolver().query(ContactsContract.Data.CONTENT_URI, projection, selection, null, null);
if (c2.moveToFirst()) {
notes = c2.getString(0);
}
It works fine with other values like name or phone number but can't seem to get notes to retrieve correctly. It retrieves a random value like email instead.
I believe that your problem is that not all rows in the table represent contact types that have notes. You have to request the proper MIME Type.
ContactsContract.CommonDataKinds.Note is an alias for the 'data1' column that is present on all rows, so when you get a row of a different MIME Type, it represents different data.
How to get contacts in Android should give you an idea of how to do this.

Query, backup, delete, insert Contacts in Android

This question should be a starting point to all of us who want to manipulate contacts in Android.
First things first
As I am aware, since API level 5 the Contacts API has changed, so in order to make the application work correct I need to check what android os is on the phone and if prior 5 use one content provider or else use the newer one. The only annoyance in this case is the warnings of deprecated I get. The application is build against Android 2.3.3 but needs to work from 1.5+
1. Querying contacts
This is the easiest part to do. Usually querying means getting data like Contact name, phones, picture, email and displaying it on a listview. For instance here is how I've done it in API prior 5
String[] projectionPeople = new String[] {People._ID, People.NAME,};
String[] projectionPhone = new String[] {Phones.NUMBER};
try {
// Get the base URI for People table in Contacts content provider.
// which is: content://contacts/people/
Uri contactUri = People.CONTENT_URI;
ContentResolver resolver = getContentResolver();
Cursor phonesCursor = null;
Cursor peopleCursor = resolver.query (contactUri,
projectionPeople, //Which columns to return.
"People.NAME is not null", // WHERE clause--we won't specify.
null, // Selection Args??
People.DEFAULT_SORT_ORDER); // Order-by name
if (peopleCursor != null && peopleCursor.getCount() >0)
{
// go to the beginning of the list
peopleCursor.moveToFirst();
do
{
//do something with current contact info
phoneUri= Uri.withAppendedPath(personUri, Contacts.People.Phones.CONTENT_DIRECTORY);
phonesCursor = resolver.query(phoneUri,
projectionPhone,
null,
null,
Phones.DEFAULT_SORT_ORDER);
if (phonesCursor!=null && phonesCursor.getCount()>0)
{
phonesCursor.moveToFirst();
lstPhones = new ArrayList<String>();
do
{
//add phone numbers to a List<String> for instance
} while (phonesCursor.moveToNext());
if (phonesCursor != null && !phonesCursor.isClosed())
phonesCursor.close();
} while (peopleCursor.moveToNext());
if (peopleCursor != null && !peopleCursor.isClosed())
peopleCursor.close();
}
}
catch (Exception ex)
{
}
}
Haven't tried it yet on the new api but the cursor should be like
final String[] projection = new String[] {
RawContacts.CONTACT_ID, // the contact id column
RawContacts.DELETED // column if this contact is deleted
};
final Cursor rawContacts = managedQuery(RawContacts.CONTENT_URI, // the URI for raw contact provider
projection
null, // selection = null, retrieve all entries
null, // selection is without parameters
null); // do not order
Sure, this needs to be elaborated a bit more, but it should provide the basics of simple query against Contacts content provider
2. Backup
My first thought on this was: if I know the Id of a Contact, I create tables in a sqlite database exactly how the cursor columns are and insert all the data into my tables. This is not an easy task as it requires a lot of codding not to mention that different apis have different table structures. What would be the best solution to backup one contact or multiple contacts ?
3. Delete
This should work on all apis using content providers, but data is spread on many packages and uris and I'm not sure from where to delete
4. Insert
After a contact is backed up, I may need to restore/insert it again. As in case of deletion, on which uris do I need to insert ?
Please, let's try to elaborate this issues so in the futures, who needs to use Contacts in Android apps could take this question as a solid starting point. Thank you stackoverflow community.
Here is a good starting point
http://developer.android.com/resources/samples/BusinessCard/index.html

Categories

Resources