update: looking at \"vnd.android.cursor.dir/vnd.google.note\"
and \"vnd.android.cursor.item/vnd.google.note\"
it seemed to me as thoug
Here is my code for multiple table query in content provider with projectionMap
//HashMap for Projection
mGroupImageUri = new HashMap<>();
mGroupImageUri.put(RosterConstants.JID,RosterProvider.TABLE_ROSTER+"."+RosterConstants.JID);
mGroupImageUri.put(RosterConstants.USER_NAME,RosterProvider.TABLE_ROSTER+"."+RosterConstants.USER_NAME);
mGroupImageUri.put(ChatConstants.MESSAGE,"c."+ChatConstants.MESSAGE+ " AS "+ ChatConstants.MESSAGE);
mGroupImageUri.put(ChatConstants.SENDER,"c."+ChatConstants.SENDER+" AS "+ChatConstants.SENDER);
mGroupImageUri.put(ChatConstants.URL_LOCAL,"c."+ChatConstants.URL_LOCAL+" AS "+ChatConstants.URL_LOCAL);
//case for content type of uri
case IMAGE_URI:
qBuilder.setTables(RosterProvider.TABLE_ROSTER
+ " LEFT OUTER JOIN "+ TABLE_NAME + " c"
+ " ON c."+ ChatConstants.JID + "=" + RosterProvider.TABLE_ROSTER + "."+RosterConstants.JID);
qBuilder.setProjectionMap(mGroupImageUri);
break;
//ContentResolver query for Projection form, selection and selection args
String[] PROJECTION_FROM = new String[]{
RosterConstants.JID,
RosterConstants.USER_NAME,
ChatConstants.MESSAGE,
ChatConstants.SENDER,
ChatConstants.URL_LOCAL
};
String selection = RosterProvider.TABLE_ROSTER +"."+RosterConstants.JID+ "='" + jid + "' AND " + "c."+ChatConstants.FILE_TYPE+"="+ChatConstants.IMAGE;
String[] selectionArgu = null;
String order = "c."+ChatConstants.MESSAGE+" ASC";
Cursor cursor = mContentReolver.query(ChatProvider.CONTENT_URI_GROUP_IMAGE_URI,
PROJECTION_FROM,selection, null,order);
//@ChatProvider.CONTENT_URI_GROUP_IMAGE_URI = 'your content type uri'
//@TABLE_NAME = 'table1'
//@RosterProvider.TABLE_ROSTER ='table2'
When creating a ContentProvider
, the expectation is that other apps are going to use your database, and with that I mean other people who know nothing about your database scheme. To make things easy for them, you create and document your URIs:
To access all the books
content://org.example.bookprovider/books
to access books by id
content://org.example.bookprovider/books/#
to access books by author name
content://org.example.bookprovider/books/author
Create as many URIs as you need, that’s up to you. This way the user of your Provider can very easily access your database info, and maybe that’s why you are getting the impression that the Provider is designed to work with one table databases, but no, internally is where the work is done.
In your ContentProvider subclass, you can use a UriMatcher
to identify those different URIs that are going to be passed to your ContentProvider methods (query
, insert
, update
, delete
). If the data the Uri
is requesting is stored in several tables, you can actually do the JOIN
s and GROUP BY
s or whatever you need with SQLiteQueryBuilder , e.g.
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder mQueryBuilder = new SQLiteQueryBuilder();
. . .
String Joins = " t1 INNER JOIN table2 t2 ON t2._id = t1._id"
+ " INNER JOIN table3 t3 ON t3._id = t1._id";
switch (mUriMatcher.match(uri)) {
case DATA_COLLECTION_URI:
mQueryBuilder.setTables(YourDataContract.TABLE1_NAME + Joins);
mQueryBuilder.setProjectionMap(. . .);
break;
case SINGLE_DATA_URI:
mQueryBuilder.setTables(YourDataContract.TABLE1_NAME + Joins);
mQueryBuilder.setProjectionMap(. . .);
mQueryBuilder.appendWhere(Table1._ID + "=" + uri.getPathSegments().get(1));
break;
case . . .
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
. . .
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = mQueryBuilder.query(db, projection, selection, selectionArgs, groupBy, having, orderBy);
return c;
}
Hope it helps.
Excuse me, but I don't understand your question.
ContentProvider is designed (a one of it's aims)to wrap access to your tabels. Design of database schema is up to you.
Generally, you need to:
Update
For JOIN operations SQLiteQueryBuilder
is usually used. In setTables()
you need to write names of tables with JOIN clause, e.g.
.setTables(NoteColumns.TABLENAME +
" LEFT OUTER JOIN " + TopicColumns.TABLENAME + " ON " +
NoteColumns.ID + " = " + TopicColumns.ID);