I have created a SQLite DB (which I am trying to use as contentProvider) and need your help to guide me on this:
1) Register a content observer (I don't know how to create URI for my Database)
2) on DB changes like update/delete row, I want to notify the contentObserver which has registered to URI of DB .
How can this be done?
You need to extend the ContentProvider class to implement your content provider.
The Android documentation walks you through the necessary steps including how to signal ContentObservers:
http://developer.android.com/guide/topics/providers/content-providers.html
Related
My problem is that I do content resolver operations (CRUD) and my local Sqlite data base gets the changes but they do not show/refresh those changes in my TEXTVIEW, in here I'm not talking about refreshing a listview/recyclerview with adapters like 100% of the questions in here I'm just talking about a simple text view which fetch information from the local database so in here I'm not using adapters or recycler views (not yet).
I've tried:
Use the database helper constructor after a new content resolver operation but is not working.
use the close() after a content provider operation.
cResolver.notifyChange() after applying a batch of operations.
I've tried to use the LoaderManager but it appears that is only useful for adapters with the swapcursor.
How do I know my CRUD ops are working? if I restart my app the changes are there. Any help in the rigth directions will be appreciated thanks.
Any change on your database is reflected only on your database. If you need to update a text view after the change, you need to handle that the change have been made and update your view.
An alternative to update your view and data after persisting it to a database is using the LiveData or any observable.
how to set the data source for a custom loader if not using content provider?
I need to populate a listview from a sqlite but do not want to create the content provider for the database, instead want to use loader to fetch data from the database. So how do I set sqlitedatabase as the data source of a custom loader?
Two options:
Use a ContentProvider and set android:exported="false" for the <provider> entry in your AndroidManifest.xml.
Copy the source code for CursorLoader and modify it to query an SQLiteDatabase instead of a ContentResolver. Then you only need to pass it a reference to your database.
Note that in order for the loader to requery, you need to properly implement data change notifications when you modify data in the database. Typically this is done using contentResolver.notifyChange() on a URI. For option 1, it should be the URI you gave to the CursorLoader; for option 2, you can manually set up a ContentObserver in your loader and do the same sort of notification, or you could implement some other signal to the loader to issue a requery.
In my app I want to show a list of apps that I have placed in an resource file.
I parse the XML(resource) file and then save the value in a SQLiteDatabase. I have implemented my Database inside a ContentProvider. What I want to know is do I need a Custom CursorLoader (should I extend CursorLoader?)? or will CursorLoader itself will be sufficient. I have seen an example, but in this no ContentProvider has been used.
Can someone explain when should I implement a Custom CursorLoader as against using the original one?
(A little unrelated) Also what would be the best practice, to implement a database with or without a ContentProvider?
Thanks in Advance!
There are many ways to implement it -
If using a ContentProvider there is no need to extend the CursorLoader.
If not using a ContentProvider and using a SQLiteDatabase instead, we can extend the CursorLoader with our Custom-Loader and override the loadInBackground() method of CursorLoader and instead of querying the ContentProvider we can query the SQLiteDatabase.
While using a SQLiteDatabase we can extend AsyncTaskLoader, however, this is more tedious method than one specified in 2.
I want registered callback method using sqlite trigger
for example,
public void printLog(){
Log.i("TAG","1 row added");
}
this method calling after insert any row in sqlite.
Is it possible?
How to do that?
SQLite provides Data Change Notification Callbacks. I don't think that Android exposes them directly but it does have for example CursorAdapter which provides some change notifications.
You can use also use the getContentResolver().registerContentObserver but unfortunately it doesn't tell you what kind of change was made, it could be a delete, insert or update.
If you control the ContentProvider that interfaces with the DB then you could fire an Intent or use getContentResolver().notifyChange to send a special Uri notification that identifies both the table and action. An example Uri you could notify with might be: content://my-authority/change/table-name/insert
But even then you don't know exactly which rows were effected by the change.
Seems like triggers that write to a change log table will guarantee you hear about all changes regardless of where they came from, and you can know the exact id and action that occurred. Unfortunately it means slower inserts/updates/deletes and it means you probably need a Service of some kind to process and delete changes.
I'd love to hear if these is some better solution out there!
You can set content observer this link will help Receives call backs for changes to content http://developer.android.com/reference/android/database/ContentObserver.html
I use standard android ContentProvider and CursorLoader from support library.
I am looking for best approach for obtain information about what has changed in database.
I know that I can read and compare cursor in function:
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
}
but reading all records is probably not good solution.
Do you know good solution for this problem?
If you use a content provider, you abstract away all the changes made to the underlying database by implementing CRUD methods to insert, update, delete or retrieve an item in the database.
Sending a broadcast from the methods which you are interested would be an option to get notified of the changes being made to the database.
I recall that I had used this method to count the number of items added to the database during a refresh cycle.
Optionally you can send the Uri of the changed item as an intent extra to get a reference to the row in the database that has been changed.
Additionally you can declare a global variable to enable or disable these broadcasts to fire only during situations of interest to us.