Using CursorLoader in android instead of startManagingCursor, database access - android

I'm new to android development and I've got a little stuck with the new API, I can't seem to find a tutorial to help.
I've got a database with a SQLOpenHelper and a Database adapter that I've seen used in many examples, such as this. I want to hook up the data into a list, so have created a ListFragment. The tutorials that I've seen use the startManagingCursor(c) method in Activity, however the documentation says that this is depreciated and to use CursorLoader.
To use the CursorLoader it looks like I need a uri, which implies I need a content provider. I don't need a content provider for my app, so I'm not sure how to implement this or what is the correct/ recommended way.
A shove in the right direction would be great!

Some points that I need to add here
Use CursorLoader instead of startManagingCursor. It is easy to use and more safe
Check The Problem with "Managed Cursors", explain that correctly
Definitely the best approach is to use content provider in front of your database to get the uri
It is very simple to implement Content provider with your db, check Simple Content Provider for db operations

From what I've read and understood, the Android team encourages the use of a ContentProvider that sits in front of your database. As you can see with CursorLoader, the Android API is also encouraging this usage pattern.
Letting aside discussions if this is the best approach for small apps, I think you should not fight the API and go with a ContentProvider. CursorLoader handles a lot of stuff for you and I find it works really well.

Yes, use ContentProvider, that's Google teams encounge to do. Remember the three layers in database book:storage, logic,application. Contentprovider act as the logic.

Related

Multiple ContentProviders in Activity like LEFT JOIN

I am using a FragmentActivity to display information from my own ContentProvider which is loaded with a CursorLoader. That ContentProvider delivers a phone number and I would like to have the name and image of that contact if available.
In the first approach I queried the ContactsContract in the CursorAdapter but that isn't the best solution as it makes the scrolling laggy even on fast devices.
I thought and searched about my problem and created 3 ways:
A left join with two ContentProviders but I found nothing about that.
Creating a custom Loader class like here.
A service wich adds the information from ContactsContract to my own ContentProvider so I only have to query one provider.
Let's discuss that. :D
Kind Regards,
k.j.
I figured out that what I was trying was not the best idea.
Now I will use a small AsyncTask when I start my app that updates my internal Database with information from ContactsContract. With that method I can use my own ContentProvider with all needed information in a very simple way. :-)

Something as awesome as ContentProvider but private (not sharing data with other apps)

I really love the concept of 'Loaders', 'ContentProviders' and especially 'ContentObservers'. I use this standard pattern where data is loaded from a local db and when it's updated from my server it's refreshed with getContentResolver().notifyChange() or something like this.
But when I use ContentProvider I have to expose my data to other apps. Why is that? I don't have any sensitive data, but it doesn't seem very elegant to me. So did I miss something here, or using ContentProvider (and thus exposing my data) is the only way to implement it easily.
What I really miss from other implementation options is to notify Loaders that new data appeared in local db.
Just to be perfectly clear here: you do not have to expose your data to other apps when you use a content provider. Instead, you can use the android:exported="false" attribute in the
element in your manifest.
Using permissions to restrict access to a provider (but not prevent it) is described in great detail in Creating a Content Provider in the Android API guide.

Do apps that won't share need Content Provider?

since i noticed the class SimpleCursorAdapter is deprecated and I should now take advantage of the new Loader APIs, which I really like, however when I tried to do so, I found out that CursorLoader works only with ContentProvider.
Now my question is, do I really need a content provider? Even the official guide says:
You don't need to develop your own provider if you don't intend to share your data with other applications. However, you do need your own provider to provide custom search suggestions in your own application. You also need your own provider if you want to copy and paste complex data or files from your application to other applications.
And I think I dont need any on this + it therefore creates unnecessary complexity.
So .. what should I do, hack my own CursorLoader to work only with my database like this (CursorLoader usage without ContentProvider), which, honestly i dont really like, or should i just suck it up and conform to making a provider?
Thanks!
You can write a Loader (or use CommonsWare's SQLiteCursorLoader) to query your SQLiteDatabase directly instead. The documentation is correct in that you don't really need a ContentProvider if your app only requires simple access to local data (as opposed to sharing that data with different processes/applications).
That said, the ContentProvider does offer a few benefits. For example, you need one to implement a SyncAdapter or a search interface with the SearchManager. I try to incorporate these into my applications so I find myself implementing ContentProviders all the time. The ContentResolver also provides an easy means of providing global notifications to the underlying data source when changes are made. For example, the CursorLoader will register a ContentObserver on its Cursor, causing the Cursor to receive a notification when you call ContentResolver#notifyChange(Uri uri, ContentObserver observer) on the given Uri. If you were to load data directly from your SQLiteDatabase instead, setting this up would require a bit more work.
Both options are as good as the other. It's a matter of preference.
Personally I think that using content provider for apps that won't share anything to other application annoying and a pain-in-the-behind, but there's a valid advice I've heard in an interview (it was from the developer of those big startup types of apps, like Pocket or Flipboard) that said: "even if might sound complicate on the beginning, do the code the Android way because it will be time/effort saver in the future"
I reckon the advice in focusing on the facts that using the recommended way, get supported, bug fixed and easier expansible faster.

When to use a Content Provider

I understand that Content Providers are made to allow publicly sharing data between applications. However, I'm wondering if anyone has thoughts about making a Content Provider to use just within your own app. Would there be any advantages to doing this? Any disadvantages?
In the past I've just implemented the SQliteOpenHelper to access data from my database, but I'm considering creating a Content Provider. I feel like the URI approach to requesting data is clear and concise. On the other hand, will using a Content Provider just for my application be redundant ( since within it I will have a SQliteOpenHelper class ) and more work than I need?
I would argue it is definitely a good idea to use a ContentProvider even if you don't intend to make it public.
It's good practice to provide the extra level of abstraction over your data to make it easier to change internally. What if you decide to change the underlying database structure at a later time? If you use a ContentProvider you can contain all the structural changes within it, where as if you don't use one, you are forced to change all areas of the code that are affected by the structural changes. Besides, it's nice to be able to re-use the same standard API for accessing data rather than littering your code with low-level access to the database.
Also, there is always the chance that you might want to expose your data in the future. If you don't use a ContentProvider up front, it will be much harder to retrofit it in at a later date.
Then, there's the other parts of the Android where ContentProvider's are required/recommended such as when using SyncAdapters and if you want an App Widget that involves data access for instance.
In summary, there is very little overhead involved in writing a ContentProvider up front (once you have learned the API which is a good idea anyway) so it makes sense to do so, even for private data.
If you are not planning to share data, don't think about Content Providers. They are powerful but hard to write and it will be just silly to implement them if you are going to use them internally.
However, I'm wondering if anyone has thoughts about making a Content Provider to use just within your own app.
Of course... for instance, for an old TODO list app I wrote, I had to write a content provider to allow other apps retrieve and access the tasks states. It was part of the requirements, but more than that it made sense and made the app nicer.
Take a look at the MOTODEV Studio for Eclipse. It is a development environment that extends Eclipse. They have a tool where you can automatically generate a content provider for a database. If a content provider makes it easier to access your data and it doesn't have a significant impact on performance go ahead and use it. In most scenarios this will be the case.
In short,Content Providers helps in managing your data effectively. I would suggest to use them for the following reasons.
It acts as an abstraction layer between your UI and database. You can implement data validation in ContentProviders to validate the data entered by the user. It also lets you to modify the structure of the database without touching the UI and other parts.
They play along nicely with other android framework classes like SyncAdapter. For eg., you can automatically refresh a list, when a value in a database changes using ContentProviders along with CursorLoader. Without ContentProviders you have to implement a lot of functionalities like these on your own.
We can safely expose our private data to other apps. Using ContentProviders will allow us to share our data easily and safely with other apps.
So even if you don't need any of these functionalities now, you might need them in future and its good to go the extra mile and implement them right now.
I agree ContentProviders are a little difficult to grasp but they are definitely helpful, even if you want to use them internally for you own app. The best thing about it is that you can customize the contentproviders for suitable URIs.
Here's a scenario where you may have 5 tables in your database, but you need to join a few of them in certain orders before using them. And make a content URI for each of these joins. You could then each use these URIs as a table :)
I suggest you go ahead with Content Provider, you'll be amazed to see how powerful it is.
In my view point, the content-provider comes with plenty of advantages leave alone just sharing data with other apps. If you need to synchronize with the server using a Sync-Adapter, use google cloud messaging, auto update the UI when the underlying data in the DB changes using Loaders, implement search, use widgets... then the content provider is for you.
I prefer you follow the guideline on because one day you may need to implement some of the above features attached to the content-provider
By the way, you can quickly build you database and CP in less than 5 minutes using content provider generator
As said in documentation:
Creating a Content provider
You don't need a provider to use an SQLite database if the use is
entirely within your own application.
So why bother developing this overhead? You want easier and faster development, right? So one layer of abstraction (SQLiteOpenHelper descendent) is enough.
See Occam's Razor
Do not make an entities without very good reason.
Using a Content Provider can help in an additional level of abstraction - Putting it within your own application make add a significant development time to your project. However if you are using it to share data, application settings or configurations across multiple applications then the Content Provider is your choice.
Watch your security levels and I would recommend using SQLcipher to encrypt data-at-reset (DAR) if your Content Provider is writing to SQLite. (I've used a content provider in a few solutions and provided the ability to take a live "snap shot" of the operational values for debugging and testing.)
Do not use content provider if do not wish to share data with other apps. Use simple sqlitedatabase to perform database operations. Be careful while using content providers for storing confidential data because your confidential information may be accessed by other apps

Exact Difference between "Content-Provider" and "SQLite Database"

i have done SQLite database programming for Android, but i dont know anything about
Content-Provider except this: "As i have referred Android Developer page , Android SDK explained about "Content-provider" as it is used to store and retrieve data."
But then,
What is the exact difference between "Content-Provider" and "SQLite Database"?
Which is best to store data, when ?
Any example or helps !!
I found one major difference, as follows:
Storing your data in a database is one good way to persist your data, but there's a caveat in Android-databases created in Android are visible only to the application that created them. That is to say, a SQLite database created on Android by one application is usable only by that application, not by other applications.
So, if you need to share data between applications, you need to use the content provider model as recommended in Android. This article presents the basics of content providers and how you can implement one.
I found this article at this link
Really nice information provided.
What is the exact difference between
"Content-Provider" and "SQLite
Database"?
ContentProvider is a facade -- an API you can implement that exposes databases to other processes. It can be implemented in a way where the data is stored in a SQLite database, but it does not have to be.
Which is best to store data, when ?
That is impossible to answer in the abstract. Generally speaking, unless something is requiring you to use a ContentProvider, just use a database.
I have made many good apps with thousands of users using them which simply used SQLite methods. But that was a while ago and I had to manually write lots of code which now can easily be taken care of by ContentProvider. Back then I was not in favour of using Content Providers because it seemed to only add complexity in the code.
However for last couple of years, as Android has evolved, I have moved to ContentProvider as it saves time and allows you do to more. I now use it extensively. Once you have a Content Provider class written, your life becomes much easier. With ContentProvider I can much easily deal with Cursor Loaders, Loader Callbacks and Bulk Inserts for which I had to write everything manually in the past and still it didn't work as efficiently. Especially when updating the list view, which is now automatically updated thanks to just one notifychange() method. This means now I don't have to type my own listeners and manually updating the content in list views and adapters. Plus, I don't need to worry about opening and closing of databases or worry about memory leaks. That's all handled by the Content Provider. The only problem which once in a while I face is that that you cannot do some complex queries in ContentProviders. In this case you can still use raw queries and use the old fashioned manual interaction with sqlite.
If you have previously written your own DbAdapter, Helper and Observer, you can safely carry them on to your new apps without spending time to convert everything to ContentProvider. But based on my experience, I would highly recommend to move to ContentProvider. It'll take some time to get used to it, but once you have got experience with it, you'll stay with it.
UPDATE 2017
I have now switched to Realm, a much better way to use databases on any platform. Spend a few hours learning it, and save countless hours in your app development career.
1. Content Providers are not Thread Safe
By default content providers are not thread safe. If you have multiple threads using a content provider you can see many different exceptions being thrown and other data inconsistencies. The easiest way to fix this is to use the synchronized keyword on each of the public methods exposed by the content provider.
In this way only one thread at a time can access these methods.
2. Play nice when doing lots of writes
I have the need in the new Serval Maps application to import data from binary files into the database used internally by the application. In order to do this and play nice with the rest of the application it is best to:
Spawn a new thread to undertake the import so other threads are not adversely impacted, in particularly the thread in charge of updating the UI; and
Pause briefly at the end of the each import to give other threads which need to use the synchronized methods more of a chance.
3. Content providers force you to think laterally sometimes
The way that content providers in Android work is to provide a layer of abstraction between the rest of your code and the underlying database. This is mainly due to the fact, as far as I can tell, that content providers can access data from places other than databases.
This means that you can’t execute raw SQL queries on the underlying database and you need to specify the various components of a SQL query using variables passed to the various methods such as the query method. If you have a task that doesn’t fit into the way that SQL is handled by a content provider you have two options:
Think laterally about the query, maybe you can get the data that you need by alternative queries and accessing the results from the cursor; and
Use a URI for accessing the data normally and a special URI that is matched to a specific query for those tasks that don’t have alternatives.
Content Providers are used when you want to share your data across applications.
If you have a database attached with an application and you want another application to use some data, you can implement a content provider that exposes the data
The main difference is: when your app needs to share information to another apps, use Content-Provider. SQLite only storage data for the app who creates it
I read this answer while looking for same doubt, so thought of sharing it.
it states -
It's good practice to provide the extra level of abstraction over your data to make it easier to change internally. What if you decide to change the underlying database structure at a later time? If you use a ContentProvider you can contain all the structural changes within it, where as if you don't use one, you are forced to change all areas of the code that are affected by the structural changes. Besides, it's nice to be able to re-use the same standard API for accessing data rather than littering your code with low-level access to the database.
So, using a content provider would be a good idea.
Think of advanced Content Management Systems. Each object (page, image, news article, event item, etc.) has a content, an address, user permissions, and ways to interact with it from different parts of the system. Content Providers do that for Android. You can now share files or images you may have stored in your application. You can also create custom sharable objects, like bussiness contacts, editable notes, etc. And specify security and the default application to deal with such object when you open them from any other application.
One difference is that Content Providers have platform support for Content Observers. Your going to need to implement your own Observable pattern for a SQLite database.
How to automatically re-query with LoaderManager
ContentObserver for SQLite?

Categories

Resources