I have a doubt that how Content resolver works, does it uses sqlite database connection implicitly for querying or how does it works and what may be the major difference in using content resolver and sqlite database connection for querying in android?
ContentResolver is used to select the specific ContentProvider.
Content Resolver provides an abstraction from the application’s Content Providers, Content Providers provide an abstraction from the underlying data source (i.e. a SQLite database).
ContentResolver --> ContentProvider --> SQLiteDatabase
I found some decent explanation about Content Resolvers & Content Providers here. It's worth a read. Hope this helps in understanding a bit more about Content Resolvers & Content Providers
Contentprovider/Contentresolver use a modell similar to sql-dabase:
projection: you have colums you are interested in (in sql select col1,col2,....)
selection or filter: find/filter rows (in sql WHERE expression)
Contentprovider can be easily implemented with a sqLite database.
But Contentprovider can also be implemented without any database.
Example: the media contentprovider (photo, video and audio files) is implemented with a sqLight database
Example: the DocumentFile contentprovider for files (in internal memory or on sdcard, on usbstick, in the cloud...) are not implemented through a database but can be queried like any other contentresolver.
*
When to use Contentproviders instead of using the raw database?
If you want to share data with other apps (example the phonebook-conacts contentprovider)
When it is essential that one app keeps control over what other apps can do. Example: Since android-7.0 access to files on sd-card is restricted to make implementing malware more difficuilt. Other apps can use the DocumentFile-provider/resolver
Related
I am about to create two applications which have the same SQLite database. I went through this link. But it does not make sense. I have to update the database from both applications. Please suggest one or more better ways.
You should read about Content Provider
Content providers are one of the primary building blocks of Android
applications, providing content to applications. They encapsulate data
and provide it to applications through the single ContentResolver
interface. A content provider is only required if you need to share
data between multiple applications. For example, the contacts data is
used by multiple applications and must be stored in a content
provider. If you don't need to share data amongst multiple
applications you can use a database directly via SQLiteDatabase.
https://developer.android.com/guide/topics/providers/content-providers
https://developer.android.com/reference/android/content/ContentProvider
Content Provider is a great way to share database with other applications.
When you create a Content Provider, you can define which part of your database can be shared as well.
A Content Provider has following parts-
1. A class that extends ContentProvider class
2. An Authority that distinguishes this ContentProvider from others on the Android O.S.
3. A Contract class that holds Uri to tables and columns that you want to share with other applications
4. A ContentResolver to access data from a ContentProvider
5. Set of user defined permissions to write to and read from a shared ContentProvider. Permissions allow only those apps that you authorize to access your ContentProvider
Here is a simple tutorial about the use of ContentProvider and how to share your database with other applications- https://www.tutorialspoint.com/android/android_content_providers.htm
I just followed tutorial in developer.android.com to create sync adapter to provider feature "synchronization between local db with server db", and after bloody trial and error i managed to make it work (onPerformSync has called successfully).
And now for next step to create sync feature, from what i have read in several articles, I need to create a content provider. I already read https://developer.android.com/guide/topics/providers/content-provider-basics.html but I still dont get it how does it work.
from this link https://developer.android.com/guide/topics/providers/content-provider-basics.html, it raised several questions in my head:
what table they are talking about? are they talking about sqlite table or some "another" table?
content://user_dictionary/words what uri is this? is this uri to table file where sqlite stored? if it's, how do I know mine? I mean where did my sqlite store table that I created?
from what I read (if i got it right), ContentProvider just like a repository. do they have same functionality? I already created my repository using anko https://gist.github.com/mockiemockiz/a552a669d28a3c90c144bc1542b86a5e , can I use that code / convert that code to be ContentProvider that able to tell sync adapter the data has changed?
I just followed tutorial in developer.android.com to create sync adapter to provider feature "synchronization between local db with server db", and after bloody trial and error i managed to make it work (onPerformSync has called successfully).
FWIW, SyncAdapter is not especially popular.
what table they are talking about?
The word "table" shows up 40 times on that page. We have no way of knowing which of those 40 concerns you, and they use the term in multiple ways.
what uri is this?
That is a Uri pointing to a collection of data ("table") in the user_dictionary ContentProvider.
is this uri to table file where sqlite stored?
That is for the developer of the ContentProvider to decide. The ContentProvider API does not stipulate where the data is stored. It could be stored in SQLite, or a JSON file, or whatever. Convention says that a collection of data exposed by a ContentProvider maps to a SQLite table or view, but that is not required.
if it's, how do I know mine?
You know it is your ContentProvider if you used user_dictionary as your authority (see android:authorities in the <provider> element in the manifest).
I mean where did my sqlite store table that I created?
That is up to you. ContentProvider has nothing to do with SQLite, unless you write code that ties a ContentProvider implementation to SQLite.
ContentProvider just like a repository
Not really, at least in terms of how I use the term "repository". A ContentProvider is a wrapper around some data storage mechanism, to allow outside parties to have controlled access to that data.
can I use that code / convert that code to be ContentProvider that able to tell sync adapter the data has changed?
That would be rather difficult. This is one of the reasons why few developers use SyncAdapter.
What is the difference between ContentProviders and ContentResolver? I do not want for the SQLite database. I am developing an application for media.
I found some explanation here. In summary
Content Resolver resolves a URI to a specific Content provider.
Content Provider provides an interface to query content.
The way to query a content provider is contentResolverInstance.query(URI,.....)
ContentProviders are used to abstract the database from other parts and acts as an interface between your database and UI/other classes. You must create your own ContentProvider to share your app data with other apps.
ContentResolver is used to select the right ContentProvider based on the ContentUris. A ContentUri may look like
content://com.android.contacts/contacts/3
content:// is called scheme and indicates that it is a ContentUri.
com.android.contacts is called Content authority and ContentResolver uses it to resolve to a unique provider (in this case, ContactProvider).
contacts is the path that identify some subset of the provider's data (for example, Table name).
3 is the id used to uniquely identify a row within the subset of data.
NOTE : Your own app can also use this route to handle its data.
See Content Providers in Android for more detail
Two layered Abstraction :
ContentResolver --> ContentProvider -->SQLiteDatabase
The main difference is this as mentioned in other answers.
ContentProvider exposes private data of your application to external application
while
ContentResolver provides the right ContentProvider among all the ContentProviders using a URI.
Deeper Understanding (of two-layered abstraction)
Let's take a detour.
We all know that when we create an SQLite database then the database remains private to your application which means, you just can not share your app data with any other external application.
How data is shared then?
ContentProvider and ContentResolver are part of android.content package. These two classes work together to provide robust, secure data sharing model among applications.
ContentProvider exposes data stored in the SQLite database to other application without telling them the underlying implementation of your database.
So it abstracts the SQliteDatabase. But wait there is a catch !!!
The external application can not directly access ContentProvider. For that, you need to first interact with another class called ContentResolver
Think ContentResolver as a ContentProvider finder. There is only one instance of it and all the ContentProviders of your Device are registered with a simple Namespace URI. If you want to reach a particular ContentProvider you just need to know its URI. Pass it to ContentResolver and it will find the Provider using the URI.
Now lets have a look at the most important method getContentResolver().query(URI,String[] proj.....)
What happens when getContentResolver().query(URI,String[] proj.....) gets called
query() method belongs to ContentResolver class however it invokes the abstract query() method of resolved ContentProvider and returns Cursor object.
In this way, the External application gets exposed to the private database via two abstraction layers.
Just to add more points
You cannot create your own ContentResolver class but you can always create your own
ContentProvider class
Hope you have a better understanding
You can also see some sample code here for creating SQLitedatabase, ContentProvider etc, But it's not well documented.
In 2021 :D
Content Resolver : For Data Request
Content Provider : For Data Response
I was wondering whether we can use the databases like (contacts.db, mmssms.db) directly instead of content providers ?
I have a reason to ask so. In my recent project, I was supposed develop a contact app. I used content provider for contact management. As I have learnt via content providers, I can query only table at a time via URIs, there is no way (at least, I didn't find) to join two tables and then get a query resolved.
And I had read, that databases are only visible to the applications that originally created them, so do my app would be able to access these databases ?
I am just a hobby developer for my own phone. I have no intention to make an app that directly uses the databases. I can pull the database from device, analyse them via sqlite. It is not that I am up against the content providers or they don't suit my need write now, it is just that it can be done or not ?
Any opinions ?
Content Providers give you a lot more than just database access. Being able to use Loaders to automatically reload your data (and update your UI) when the underlying data changes can vastly simplify your applications.
The goal of Content Providers is more to create a single, controlled layer for accessing your data. There is nothing stopping you from creating a custom URI that joins multiple tables together and returns the resulting joined result.
Is it possible to create a custom ContentProvider to
Access android existing database (e.g. Contacts, SMS)?
Extend an Exciting ContentProvider which has access to android existing database (e.g. ContactsProvider to access Contacts DB)?
Thank you.
Short Answer: Yes
Longer answer:
ContentProviders are a layer sitting in between the "outside world" (e.g. other Android Activities) and the back-end data storage. You will never have direct access to the database. The database is stored in the Activities private storage space. So all you can do is dictated by the ContentProvider you are addressing.
If the ContentProvider only allows read-only access to the data, than that is all you can do.
So in the end, you can only offer access which has at most the kind of access as the ContentProvider you are using. You can however expose a different data structure. Or you could also create one ContentProvider which uses multiple other providers internally.
On the bottom line, within the given bounds, your imagination is the limit.