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.
Related
I have an app that gets the ContactsContract.Contacts.LOOKUP_KEY of a contact on the device and saves it on the app Db.
After reading this page I thought I could use the LOOKUP_KEY to uniquely identify a contact, even when a contact is edited (for example after editing the name of the contact).
Actually I saw that after editing a contact, its LOOKUP_KEY changes, so I cannot use anymore the LOOKUP_KEY I saved on my app DB.
My question is: is there a way to uniquely identify a contact on ContactsContract.Contacts from when it is created for the first time on the device until it is deleted from the device?
Thank you
A LOOKUP_KEY is not meant to be used as a key on its own, instead it should be used together with a contact's _ID to form a full lookupUri.
The lookupUri can then be used to find a contact in CONTENT_LOOKUP_URI tables.
The CONTENT_LOOKUP_URI basically first looks for the contact by _ID, if it fails to find it, or the _ID seems like the wrong contact, it uses hints from the LOOKUP_KEY part to try and track down the correct contact for you.
From CONTENT_LOOKUP_URI
A content:// style URI for this table that should be used to create
shortcuts or otherwise create long-term links to contacts. This URI
should always be followed by a "/" and the contact's LOOKUP_KEY. It
can optionally also have a "/" and last known contact ID appended
after that. This "complete" format is an important optimization and is
highly recommended.
As long as the contact's row ID remains the same, this URI is
equivalent to CONTENT_URI. If the contact's row ID changes as a result
of a sync or aggregation, this URI will look up the contact using
indirect information (sync IDs or constituent raw contacts).
Lookup key should be appended unencoded - it is stored in the encoded
form, ready for use in a URI.
From getLookupUri(long contactId, String lookupKey)
Build a CONTENT_LOOKUP_URI lookup Uri using the given _ID and
LOOKUP_KEY.
From LOOKUP_KEY
An opaque value that contains hints on how to find the contact if its
row id changed as a result of a sync or aggregation.
The row id (primary key) for each contact called _ID.
I am baffled by notifyChange machenism used in contentProvide:
// Tell the cursor what uri to watch, so it knows when its source data changes
c.setNotificationUri(getContext().getContentResolver(), uri);
and
getContext().getContentResolver().notifyChange(noteUri, null);
Here are the questions (suppose the provider and the client are in different packages):
Is the contentResolver returned by Provider the same as Resolver returned by the client?
Is the cursor the same as returned by the provider and the client?
what is the Uri resolution to be notified changes? the entire table uri or a row?
Please clarify
I know this is an old question. I am answering so that it is helpful for someone who comes across this question.
Is the contentResolver returned by Provider the same as Resolver returned by the client?
Yes, it is the same.
Is the cursor the same as returned by the provider and the client?
I suppose, you are asking this in the context of your first code snippet which is seen inside query() method. Here, you are setting the notification uri on the cursor which is to be returned to the client. So, obviously, the client and the provider are using the same cursor.
what is the Uri resolution to be notified changes? the entire table uri or a row?
Uri for notification depends on the operation:
insert() - The notification Uri is the table Uri appended with the
id of the newly inserted row.
delete() and update() - Here, the Uri is the table Uri appended with the id of the deleted or updated row.
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.
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.
from google example below
As an example of designing and coding content URI handling, consider a provider with the authority com.example.app.provider that recognizes the following content URIs pointing to tables:
content://com.example.app.provider/table1: A table called table1.
content://com.example.app.provider/table2/dataset1: A table called dataset1.
content://com.example.app.provider/table2/dataset2: A table called dataset2.
content://com.example.app.provider/table3: A table called table3.
I am confused here. Does this example mean that Table1Contentprovider, Table2ContentProvider, Table3ContentProvider are pointing at the same authority url? From what I read, each provider should have unique authority url.
Or does it mean, there is only one provider here that works all 3 tables? If that is the case, in the query method of the provider do we run sql query to get data related to all three tables?
from google example below
Actually, it is from this page, not the one you linked to.
Does this example mean that Table1Contentprovider, Table2ContentProvider, Table3ContentProvider are pointing at the same authority url?
There is only one provider, not three ("consider a provider").
From what I read, each provider should have unique authority url.
A ContentProvider can support multiple authorities, via a comma-delimited list in the android:authorities attribute, though most of the time they only support one.
Or does it mean, there is only one provider here that works all 3 tables?
Correct.
If that is the case, in the query method of the provider do we run sql query to get data related to all three tables?
In methods like query(), you examine the Uri that you are supplied and perform the operations specific to the supplied path. In the aforementioned example, query() would look to do different things for the paths table1, table2/dataset1, table2/dataset2, and table3.