I have a database and within the database i have 3 tables but im using a content provider so how can i distinguish between the tables? i understand the format of the uri and that i would have to use a separate path for each but how do i get the value of the uri with the different paths. do i need to use uri matcher and then that will return the uri i want based on what i put in the parameters? from what i found online it looked like uri matcher was only used for the get type method in the content provider.
do i need to use uri matcher and then that will return the uri i want
based on what i put in the parameters?
Correct. Each of the ContentProvider's methods is called with a Uri parameter. You can simply pass that to your UriMatcher and then continue in a switch statement.
Related
I am using CursorLoader to populate my listView.
But I need to get distinct result set.
But CursorLoader has no constructor to set distinct parameter.
Any Suggestions?
Yes!
In the CursorLoader constructor you specify a URI. Part of that URI is the ContentProvider Authority. The rest, though, is up to you! So create a virtual table!
If you have a table "songbirds", perhaps your URI is:
content://my.content.provider/songbirds
Simply teach your ContentProvider (add one more clause to your UriMatcher) to recognize the URI:
content://my.content.provider/distinctSongbirds
Process the "distinct" URI exactly as you do the non-distinct one, except add a "distinct" param to the actual DB query, when you make it.
I have several questions related to the official LoaderManager example when implementing filtering in an application (i.e. SQLite database, using Content Provider, using CONTENT_URI when no filtering is used, or forming the URI for filtering via concatenation of the CONTENT_FILTER_URI and the content of the mCurFilter variable.
Fistly, I need confirmation, that I understand the filtering URI correctly. Earlier, I did use the CONTENT_URI and set the selection, selectionArgs, and sortOrder when creating new CursorLoader(...) in the onCreateLoader method of the activity that implements LoaderManager.LoaderCallbacks<Cursor>. I did not understand why others use a special CONTENT_FILTER_URI.
The official example passes null for the selectionArgs, and the filter value is probably extracted as filter = uri.getLastPathSegment(); and added used for the selectionArgs. In my case, I am passing null also for the selection and forming it in the content provider like:
selection = ProductTable.COLUMN_NAME + " like ?";
selectionArgs = new String[]{ "%" + filter +"%" };
My understanding now is that:
The filter value can be used also other ways than simply put to a simple and single SQL command, and this is the reason to use the CONTENT_FILTER_URI.
The CONTENT_FILTER_URI makes getting the information more abstract, i.e. less SQL specific, more web-service like access to the data.
With respect to that, I am still confused why also the sortOrder is not expressed in the URI somehow. Is it a kind of tradeoff? (I hope the official example simply does not take a slopy approach, and there is real reason to form the select argument outside the content provider.)
Should I always parse the user-entered filter value? The reason is that a user can enter whatever filter value -- also the forbidden characters can be inserted. This way the unknown URI path can be formed and the URI may not be recognized. Or even worse, there may be a chance that some kind of SQL injection can be done, or at least the application can be crashed. Am I too paranoic when thinking about URI and the injection errors? Are there some rules or tools mentioned at developer.android.com or elsewhere that are related to the problem?
I've been researching ContentProviders for a while now and I'm still having trouble grasping how exactly the Uri works.
content://app_name/path/id
When a path is specified how does the table corresponding to that path gets accessed?
It seems like you would need to label the table with that path. Is it so?
You are right google docs on this point are not very clear :
First : you must define an authority for a custom provider :
http://developer.android.com/guide/topics/providers/content-provider-creating.html#ContentURI
<provider
android:name=".ProviderDemo"
android:authorities="com.foo.android.providerdemo" />
Second : use this authority when you query a provider :
http://developer.android.com/guide/topics/providers/content-provider-creating.html#ContentURI
//query all items
getContentResolver().query("content://com.foo.android.providerdemo/",...)
//query a single item
getContentResolver().query("content://com.foo.android.providerdemo/idOfItem>",...)
//query a view
getContentResolver().query("content://com.foo.android.providerdemo/<idOfView>/",...)
To help you choose which action to take for an incoming content URI, the provider API includes the convenience class UriMatcher, which maps content URI "patterns" to integer values. You can use the integer values in a switch statement that chooses the desired action for the content URI or URIs that match a particular pattern.
My confusion came from a lack of SQLite knowledge. I was unaware that a database holds many tables and not just 1 table. Now I realize that the authority of the Uri must take you to the database and then the path will take you to the correct table.
I'm trying to build a Content_Provider but i'm stuck on Base_path....
For example I have table name arrival like below :
How can I name a CONTENT_URI ?
Can anyone help me out ?
Thanks in advance !
From the docs:
A content URI is a URI that identifies data in a provider. Content URIs include the symbolic name of the entire provider (its authority)
and a name that points to a table (a path). When you call a client
method to access a table in a provider, the content URI for the table
is one of the arguments.
In the preceding lines of code, the constant CONTENT_URI contains the content URI of the user dictionary's "words" table. The
ContentResolver object parses out the URI's authority, and uses it to
"resolve" the provider by comparing the authority to a system table of
known providers. The ContentResolver can then dispatch the query
arguments to the correct provider.
The ContentProvider uses the path part of the content URI to choose the table to access. A provider usually has a path for each
table it exposes.
In the previous lines of code, the full URI for the "words" table is:
content://user_dictionary/words
where the user_dictionary string is the provider's authority, and words string is the table's path. The string content:// (the scheme)
is always present, and identifies this as a content URI.
So in a content_uri, you have an authority and a base_path. The ContentResolver will use the authority part to decide which provider to choose and then the base_path part to decide which table to provide the data from. So, simplifying, the base_path is usually the path for your particular table within your provider.
Refer this guide for more and go through this tutorial as well.
I'm trying to structure a URI that accesses my data by id.
Currently my URIs are query based like so:
.../content?parentList=15&type=note
How could I structure a similar URI so that I could query for notes in multiple lists?
Essentially combining the results of the next two URIs.
.../content?parentList=15&type=note
.../content?parentList=16&type=note
Is there a standard way to do this?
According to the current draft of the URI Template spec (Section 3.6 on page 7), you could do:
.../content?parentList=15,16&type=note
The Query portion of the URI doesn't require each parameter to occur only once. Just repeat the query:
.../content?parentList=15&parentList=16&type=note
It is also part of the URI template internet draft:
{?list+}
becomes
?list=val1&list=val2&list=val3