I want to know the context in which getContentResolver() is called?
I have a scenario like this:
I have an activity A that calls a method myFunc() of class B which is not an activity.
So, in class B I have to use getContentResolver(). I directly called getContentResolver(). It was showing error. Then I called myFunc(Acitivy act) from the activity and called act.getContentResolver() which solved my problem. Is this the only way to call getContentResolver(), which means it can be used in context with activity or can be used alone.
getContentResolver() is method of class android.content.Context, so to call it you definitely need an instance
of Context ( Activity or Service for example).
You can use like this:
getApplicationContext().getContentResolver()
with the proper context.
The getContentResolver()method is also used when you query a Contact, using a Cursor object. I have used getContentResolver() to query the Android phone Contacts app, looking for contact info from a person's phone number, to include in my app. The different elements in a query (as shown below) represent what kind of contact details you want, and if they should be ordered, etc. Here is another example.
From the Content Provider Basics page from Android docs.
// Queries the user dictionary and returns results
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder); // The sort order for the returned rows
import android.content.Context;
import android.content.ContentResolver;
context = (Context)this;
ContentResolver result = (ContentResolver)context.getContentResolver();
//create activity object to get activity from Activity class for use to content resolver
private final Activity ActivityObj;
//create constructor with ActivityObj to get activity from Activity class
public RecyclerViewAdapterClass(Activity activityObj) {
this.ActivityObj = activityObj;
}
ActivityObj.getContentResolver(),.....,.....,null);
Access contentResolver in Kotlin , inside activities, Object classes &... :
Application().contentResolver
This one worked for me
getBaseContext();
A solution would be to get the ContentResolver from the context
ContentResolver contentResolver = getContext().getContentResolver();
Link to the documentation : ContentResolver
Related
I am a bit confused about CursorLoader and a regular call with the Content Resolver :
There is an example with the CursorManager : (http://developer.android.com/reference/android/app/LoaderManager.html) ,
where we use return new CursorLoader to fetch the data.
And another example with contentResolver, to insert some data in the content Provider :
mUri = getContentResolver().insert(intent.getData(), null);
What if we wanted to use a Loader instance to insert data in the content provider, instead of, like in the example above, just query the data. How should we do? And would it be necessary?
Thanks
Loaders are not for insert/update/delete queries, only for loading data. You'd want to use an AsyncQueryHandler to do those operations (best for operations tied to user interactions):
AsyncQueryHandler handler = new AsyncQueryHandler(getContentResolver()) {
#Override
protected void onInsertComplete(int token, Object cookie, Uri uri) {
// Do something now that your insert is complete
}
};
handler.startInsert(
0, // token, passed on to onInsertComplete
null, // cookie, passed on to onInsertComplete
initialValues); // ContentValues to insert
I am new in Android and am implementing a content provider for 5 tables.
My Questions Are:
Should I have a Content Provider for each table or multiple tables in a single
Content provider? Since the Content Provider has a single insert, update, query, delete methods.
How can I include only one Content Provider in my application? I have searched and in Most of the examples, I only find a single table apps.
Where do I have to use switch conditions to support multiple tables with the same Content Provider?
please give me some idea.
You can use the URI parameter:
List<String> android.net.Uri.getPathSegments()
If your URI is, for example:
content://com.mypackage.MyContentProvider/MyTable
MyTable will be in the list returned by getPathSegments();.
Then you have to specify your table in the URI and in insert, update, query, delete methods in provider build a query depending on the URI parameter.
To avoid testing on URI you can add to you provider an Abstract method called getTableName() witch will return your tableName as String.
Then extend your provider to 5 classes Table1Provider, Table2Provider etc. and implement method
Class abstract MyProvider extends ContentProvider{
public abstract String getTableName();
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
///...
// Set the table
queryBuilder.setTables(getTableName());
//...
return cursor;
}
}
class Table1Provider extend MyProvider{
public String getTableName(){
return "Table1";
}
Then instantiate the Table1Provider instead of the abstract provider.
Make one provider. Use the URIMatcher class provided by Android to match content URIs with different tables.
Read here: http://developer.android.com/guide/topics/providers/content-provider-creating.html#ContentURI
Suppose you have a CONTENT_URI inside your ContentProvider in which you want to do some complex stuff and return a combination of Cursors (MergeCursor) instead of a simple, single Cursor.
It so happens that if you set the notification URI on the MergeCursor instead of a cursor from within that MergeCursor, the notification is not going to work.
Initial code:
Cursor[] cursors = { extraCursorBefore, usersCursor, extraCursorAfter };
Cursor extendedCursor = new MergeCursor(cursors);
// Make sure that potential listeners are getting notified
extendedCursor.setNotificationUri(getContext().getContentResolver(), CONTENT_URI_PEOPLE);
return extendedCursor;
PS: If by any means, somebody has another idea, or figures out why the hell this didn't work on the original MergeCursor, then please, share your knowledge.
So you need to set the notification URI on a Cursor from within the resulting MergeCursor.
Code that actually works:
Cursor[] cursors = { extraCursorBefore, usersCursor, extraCursorAfter };
Cursor extendedCursor = new MergeCursor(cursors);
// Make sure that potential listeners are getting notified
usersCursor.setNotificationUri(getContext().getContentResolver(), CONTENT_URI_PEOPLE);
return extendedCursor;
I use a ContentProvider in my app and everything works great except for one little issue. I have a backup and restore function that backs up the database to a file on the SD card and then those backup files can be restored to overwrite the current database. This whole process is working, but the ContentProvider still holds the reference/cache to the original database once one of the old backup files is restored. I can't seem to find a way to refresh or reload the database reference in the ContentProvider. I know the restore works because I can see the records in the db with SQLite Editor and when I close and re-open the app, it displays the correct records.
Does anybody know a way to do this? Is there a way to close and re-open the ContentProvider that I'm not seeing?
If you are targeting >= API 5 you can get a reference to your ContentProvider via a ContentProviderClient, and run a method specific to your implementation:
ContentResolver resolver = context.getContentResolver();
ContentProviderClient client = resolver.acquireContentProviderClient("myAuthority");
MyContentProvider provider = (MyContentProvider) client.getLocalContentProvider();
provider.resetDatabase();
client.release();
Add the reset method to your ContentProvider implementation:
public void resetDatabase() {
mDatabaseHelper.close();
mDatabaseHelper = new MyDatabaseOpenHelper(context);
}
Are you maintaining a reference to the actual SQLiteDatabase in your content provider (something like calling SQLiteOpenHelper.getWritableDatabase() in onCreate() and then keeping that reference)? Or do you get the DB object from someplace like a helper in each provider method?
Typically, if you only keep a local reference to the helper and get the writable/readable database instance inside of each method as needed then this problem should go away. If not, perhaps we can take a look at the provider code?
Hope that Helps!
Here is my solution.
public class DataProvider extends ContentProvider {
private DataDbHelper dbHelper;
#Override
public boolean onCreate() {
// nothing here
return true;
}
private DataDbHelper getDbHelper() {
if (dbHelper== null) {
// initialize
dbHelper = new DataDbHelper(getContext());
} else if (dbHelper.getReadableDatabase().getVersion() != DataDbHelper.VERSION) {
// reset
dbHelper.close();
dbHelper = new DataDbHelper(getContext());
}
return this.mOpenHelper;
}
}
query(), insert(), update(), delete() use getDbHelper() to obtain an SQLiteDatabase
The full code of my Android app is available here if you need more info.
You can also simply use the delete method without a selection:
context.getContentResolver().delete(YourProvider.CONTENT_URI, null, null);
Is there any way to get Cursor for a query, which I am processing with ORMLite Dao object?
ORMLite now supports next(), previous(), moveRelative(offset), ... methods on the CloseableIterator class. This should allow you to move the underlying Cursor object around at will.
It also supports the following DAO Cursor methods:
dao.mapSelectStarRow(databaseResults) Return the latest row from the database results from a query to select *. With this you can change the cursor location (for example) and then get the current object.
dao.getSelectStarRowMapper() Provides a mapper that you can use to map the object outside of the Dao.
When you are building your own query with ORMLite, you use the QueryBuilder object. queryBuilder.prepare() returns a PreparedQuery which is used by various methods in the DAO. You can call dao.iterator(preparedQuery) which will return a CloseableIterator which is used to iterate through the results. There is a iterator.getRawResults() to get access to the DatabaseResults class. Under Android, this can be cast to an AndroidDatabaseResults which has a getCursor() method on it to return the Android Cursor.
Something like the following code:
// build your query
QueryBuilder<Foo, String> qb = fooDao.queryBuilder();
qb.where()...;
// when you are done, prepare your query and build an iterator
CloseableIterator<Foo> iterator = dao.iterator(qb.prepare());
try {
// get the raw results which can be cast under Android
AndroidDatabaseResults results =
(AndroidDatabaseResults)iterator.getRawResults();
Cursor cursor = results.getRawCursor();
...
} finally {
iterator.closeQuietly();
}
This is a bit complicated but you are definitely having to peer behind the vale to get to this object which is hidden by the database abstraction classes.
Did you try some of Gray's advice from this post? He explains how you can select a column as another name, such as, select id as _id.
If you're in an Activity and don't want to mess around with the QueryBuilder give the following a go, which is just as effective.
Cursor cursor = getHelper().getReadableDatabase().query(tableName, projection, selection, selectionArgs, groupBy, having, sortOrder)
If you mean the getHelper() method to reach the dao methods create etc. you only have to inherit from the OrmLiteBaseActivity<YourDBHelper> and you can call it. It will look sth like this:
public class YourClass extends OrmLiteBaseActivity<YourDBHelper> {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
getHelper().getDao().queryForAll();
...
}
}
If you mean the cursor to handle database operation: I don't think that you can reach it! But I don't understand why you should need it. ORMLite has nearly all functions of the cursor. So what do you need it for?