ContactsContract.Data._ID value is always the same - android

I am querying a user profile data on an Android Phone using the following URI:
Uri.withAppendedPath(Profile.CONTENT_URI, ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
All ContactsContract.Data rows seem to be returned correctly (structured names, phones,email, web, etc). The problem I am having is that
curData.getLong(curData.getColumnIndex(ContactsContract.Data._ID));
returns the same value for every row, even though other columns have different values. Could somebody help me understand why is this happening? How can I distinguish one ContactsContract.Data row from another?

Just found out that Entity.DATA_ID should be used instead of ContactsContract.Data._ID when querying ContactsContract.Data rows through Entity URIs.

Related

Trouble linking results from 2 CursorLoaders

I am using the contact intent to get a contact ID and I am then using a CursorLoader to firstly get the following columns
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.Contacts.PHOTO_ID
Then I will use the PHOTO_ID in a second CursorLoader to get the Photo Blob.
I will then use information from both CursorLoaders results to populate a GridView.
I need to store the data returned form the first CursorLoader and combine it with the Photo blob from the second CursorLoader. The id returned from the contact selection seemed the perfect key for a small map.
This works fine on the assumption that a single contact will be selected. I will have two versions of the app though and the other version will allow up to three contacts (using a custom ListView rather than the intent).
I thought that I could return the same _ID column in both CursorLoaders and use that as a common key, but strangely, because the URI for each CursorLoader is different so is the value of the _ID column...
Can anyone point me in the right direction please? I need to link the results from the two CursorLoaders together somehow...

ContentProvider/ContentResolver Query Sorting by ID by default

I am working on an application that stores everything in a database and it is accessed using a ContentProvider. My scenario is as follows:
I make a web call and receive a list of integers which represent the ids of the objects I need to retrieve from my database on the device.
I make a call to ContentResolver.query() with the following Selection:
Selection: _id=? OR _id=? OR _id=?
Selection Ids: 30; 165; 149;
So, I need to get all items where the id is either 30, 165, or 149. And I need them in that exact order.
This is the exact call I am making on the ContentResolver:
Cursor cursor = mActivity.getContentResolver().query(myUri, null, selection, selectionIds, null);
As you can see, I do not pass in any sorting. However, the result gives me a Cursor with the order being the following: 30, 149, 165. So, it appears it is defaulting the sorting by _id even though I do not specify any sort order. My question is, does anyone know of a way to stop this from happening?
When you select rows, from any database, without specifying an ORDER BY clause, you should consider the order of the results as undefined, i.e. it could come back in any order. The reason you are seeing it sorted by _id here is just due to circumstance - they are likely to be in that order on the underlying database files so that is the order SQLite reads them back in. However it is not safe to assume that will always be so.
So the actual answer to your question is no, you can't assume SQLite will return your rows in any particular order without an ORDER BY clause. If you are unable to provide such a clause (which appears to be the case here) you'll have to sort them in code after getting all the data from the cursor.
It is not defaulting to _id, it is giving you the records as they are in the db (which happen to be sorted by id). Pass your own sorting order if you don't want this.

Android SQLite Update stops working after calling it two times

I have problems in updating rows in SQLite database in my Android application. It works successfully only, if I update it two times. But when I try to do it on the third time, it doesn't update the same row anymore.
LogCat doesn't show any exceptions. db.update() returns '1'.
I've searched similar issues on StackOverflow and the web. People advic]sed to remove db.close(); from database-helper, because I call it several times, or to use db.update method instead of db.rawQuery() or db.execSQL().
I also tested my query in SQLite client, and it works as it's supposed to.
Here is code of simple database-helper method:
public int updateEventDoneMark(Event event)
{
ContentValues args = new ContentValues();
args.put("completed", event.getCompleted());
return db.update("Event", args, "id" + "='" +event.getId() + "'", null);
}
Is there some SQLite-related issue I should know while I update one database entry several times in a row?
What does your content provider update and URI match look like?
Typical Content providers have a URI for each Table/View for a single row where _id is passed as a where_argument and a URI for multiple rows which uses where and where_arguments to select the rows to be updated.
Also it looks like you update by id. Android really want the id column named "_id", although I don't think is currently your issue, but it really depends on the URI it's using. Content Providers are usually coded with the _id and select by the column for a single row based on _id. That's why I want to see content provider. Your also selecting by the id yourself, this doesn't seem normal, although it could be accomplished, but not the norm. Typically the where part is something like 'colunm name = ?" and the next parameter where_arguments is a string array containing the value to replace the '?'.
Hope this helps.

Is it possible to compare two cursors?

I need to check if two cursors pointing at the same rows with the same values. Is it possible?
More details:
I'm loading data from my own ContentProvider
I'm sending request to server and then updating my data inside ContentProvider with new values.
If values is changed - I need to notify user that he can update data.
As per CommonsWare's deleted answer:
Iterate over the relevant columns in the Cursor, retrieve the values, and compare each.
Although you may not know in advance the type of each column, you can find out with Cursor.getType(). You can also use Cursor.getColumnNames() to get the name of each column, and the number of columns.
This information will allow you to then use the correct accessor method to obtain each value and compare.
In SQLite, rows do not have an identity separate from their column values (but the ROWID is one of these values).
What you want requires that your data has some unique column(s) as part of the cursor, either the ROWID, or some other key value that is guaranteed to have no duplicates.
Otherwise, you can never know if what you see is just two records that happen to have the same values in those columns.

in Android 2.0 or later, is it possible to identify all the raw contacts from which a single aggregate contact is formed?

as far as you might know, there are contacts (aggregate contacts) which are formed by aggregation of two or more raw contacts in Android V2.x
is it possible to identify all the raw contacts from which a single aggregate contacts is formed through a query on the ContactsContract.Contacts or is there a way to identify these
contacts at all?
i could not find any flag or database field that tells me that this aggregate contacts is linked with these raw contacts.
any suggestions?
You can check AggregationExceptions.CONTENT_URI Table where relationship type are AggregationExceptions.TYPE_KEEP_TOGETHER, AggregationExceptions.TYPE_KEEP_SEPARATE, etc.
and you can find Raw_contact_id1 and raw_contact_id2.
Example of data into database. Lets say 1,2,3,4 are in relation so you can find following pairs.
Raw_contact_id1 raw_contact_id2 Relationship type
1-> 2, 1->3, 1->4, 2->3, 2->4, 3->4
A Contact cannot be created explicitly. When a raw contact is inserted, the provider will first try to find a Contact representing the same person. If one is found, the raw contact's CONTACT_ID column gets the _ID of the aggregate Contact. If no match is found, the provider automatically inserts a new Contact and puts its _ID into the CONTACT_ID column of the newly inserted raw contact.
So, while reading all the contacts one by one we can take its _ID value and can retrieve all the contacts from raw_contacts where _ID matches with raw_contacts.CONTACT_ID.
If the count is greater than 1 then we can conclude that it is linked with those numbers of contacts else it is not linked with any other contact.

Categories

Resources