Trouble linking results from 2 CursorLoaders - android

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...

Related

reading specific contact information

I'm currently doing development on an Android app that requires me to read all the contacts on a device and select only specific contacts based on criteria (only contacts that have at least one valid mobile number and all email addresses linked to that contact).
I've tried the recommended approach at https://stackoverflow.com/a/19563999/3262731, but on a test device with approximately 800 contacts, retrieving all the records and then filtering takes about 17-20 seconds.
Ideally I'd love to build the criteria into a query that joins the contacts, phone, and email store tables in the contacts db as opposed to filtering in my code.
Does anyone have any suggestions please?
The android documentation seems to contain information in what you're looking for found here.
private static final String[] PROJECTION =
{
/*
* The detail data row ID. To make a ListView work,
* this column is required.
*/
Data._ID,
// The primary display name
Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
Data.DISPLAY_NAME_PRIMARY :
Data.DISPLAY_NAME,
// The contact's _ID, to construct a content URI
Data.CONTACT_ID
// The contact's LOOKUP_KEY, to construct a content URI
Data.LOOKUP_KEY (a permanent link to the contact
};
return new CursorLoader(getActivity(), contentUri, PROJECTION, SELECTION, SELECTION_ARGS, SORT_ORDER);
More details on how to define your criteria in the documentation. I would think this would be faster than using a ContentResolver as well.
According to http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html
Query
If you need to read an individual contact, consider using CONTENT_LOOKUP_URI instead of CONTENT_URI.
If you need to look up a contact by the phone number, use PhoneLookup.CONTENT_FILTER_URI, which is optimized for this purpose.
If you need to look up a contact by partial name, e.g. to produce filter-as-you-type suggestions, use the CONTENT_FILTER_URI URI.
If you need to look up a contact by some data element like email address, nickname, etc, use a query against the ContactsContract.Data
table. The result will contain contact ID, name etc.

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.

LoaderManager.onLoadFinished is called even when the specific query doesn't match the update

I have a Android app which has a Content Provider which I update frequently. To load the lists of the said data, I'm using a LoaderManager.
On the detail page, I also use a LoaderManager, but I create the CursorLoader like this:
return new CursorLoader(getActivity(), DataProvider.POST_URI, projection, "_id = ?", new String[]{String.valueOf(post_id)}, null);
As you can see, I'm only getting a single item from the table. When the row is updated the the onLoadFinished callback is updated, but, also, when other rows are added/modified to the table. It wouldn't be much of a hassle, but sometimes, it causes the whole list to get blank and redrawn, which can be frustrating for the user when it happens multiple times.
Do you know how could I avoid this behavior?
The reloading is taking place because you are associating this cursor loader with the DataProvider.POST_URI which I assume is the one you use for your posts table. Whenever there is a change in any of the elements in this table, all the cursors with that Uri will be notified. If you want to receive notification of a single item you should implement a new Uri scheme to match just that one item. Have a look at the documentation for the UriMatcher class for an example. You should do something similar to the PEOPLE and PEOPLE_ID cases.
EDIT
You can find a good tutorial on ContentProvider here. Section 9.4 in special should be helpful in correctly implementing the ContentProvider.

ContactsContract.Data._ID value is always the same

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.

Content Provider filtering query, filtering Cursor

I got following problem, I need to use a Content Provider to read a
Database of an other App.
first I want all rows, and after analyzing the data only e.g. the rows
from _id = 1, 3 and 5.
how can I call a Content provider and select only these rows?
or is it possible to create a subset Cursor form an given Cursor?
Thanks in advance.
If you're talking to another app, I assume you're querying the other app's ContentProvider to get the data from them in the first place.
In this situation, the cleanest answer seems not to build your own ContentProvider that filters/wraps theirs. Instead query their ContentProvider from your application directly, and use the select clause in your query() to specify the conditions that define the subset of data you want to be given.

Categories

Resources