我找到了一个最好的演示和解释
ContentProvider 的内容,我认为它遵循了Android标准。
合同类
public static final String CONTENT_AUTHORITY = "com.androidessence.moviedatabase";
private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final String PATH_MOVIE = "movie";
public static final String PATH_GENRE = "genre";
和内部类:
public static final class MovieEntry implements BaseColumns {
public static final Uri CONTENT_URI =
BASE_CONTENT_URI.buildUpon().appendPath(PATH_MOVIE).build();
public static final String CONTENT_TYPE =
"vnd.android.cursor.dir/" + CONTENT_URI + "/" + PATH_MOVIE;
public static final String CONTENT_ITEM_TYPE =
"vnd.android.cursor.item/" + CONTENT_URI + "/" + PATH_MOVIE;
public static final String TABLE_NAME = "movieTable";
public static final String COLUMN_NAME = "movieName";
public static final String COLUMN_RELEASE_DATE = "movieReleaseDate";
public static final String COLUMN_GENRE = "movieGenre";
public static Uri buildMovieUri(long id){
return ContentUris.withAppendedId(CONTENT_URI, id);
}
}
public static final class GenreEntry implements BaseColumns{
public static final Uri CONTENT_URI =
BASE_CONTENT_URI.buildUpon().appendPath(PATH_GENRE).build();
public static final String CONTENT_TYPE =
"vnd.android.cursor.dir/" + CONTENT_URI + "/" + PATH_GENRE;
public static final String CONTENT_ITEM_TYPE =
"vnd.android.cursor.item/" + CONTENT_URI + "/" + PATH_GENRE;
public static final String TABLE_NAME = "genreTable";
public static final String COLUMN_NAME = "genreName";
public static Uri buildGenreUri(long id){
return ContentUris.withAppendedId(CONTENT_URI, id);
}
}
现在使用
SQLiteOpenHelper创建数据库:
public class MovieDBHelper extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "movieList.db";
public MovieDBHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
addGenreTable(db);
addMovieTable(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
private void addGenreTable(SQLiteDatabase db){
db.execSQL(
"CREATE TABLE " + MovieContract.GenreEntry.TABLE_NAME + " (" +
MovieContract.GenreEntry._ID + " INTEGER PRIMARY KEY, " +
MovieContract.GenreEntry.COLUMN_NAME + " TEXT UNIQUE NOT NULL);"
);
}
private void addMovieTable(SQLiteDatabase db){
db.execSQL(
"CREATE TABLE " + MovieContract.MovieEntry.TABLE_NAME + " (" +
MovieContract.MovieEntry._ID + " INTEGER PRIMARY KEY, " +
MovieContract.MovieEntry.COLUMN_NAME + " TEXT NOT NULL, " +
MovieContract.MovieEntry.COLUMN_RELEASE_DATE + " TEXT NOT NULL, " +
MovieContract.MovieEntry.COLUMN_GENRE + " INTEGER NOT NULL, " +
"FOREIGN KEY (" + MovieContract.MovieEntry.COLUMN_GENRE + ") " +
"REFERENCES " + MovieContract.GenreEntry.TABLE_NAME + " (" + MovieContract.GenreEntry._ID + "));"
);
}
}
内容提供者:
public class MovieProvider extends ContentProvider {
private static final int GENRE = 100;
private static final int GENRE_ID = 101;
private static final int MOVIE = 200;
private static final int MOVIE_ID = 201;
private static final UriMatcher sUriMatcher = buildUriMatcher();
private MovieDBHelper mOpenHelper;
@Override
public boolean onCreate() {
mOpenHelper = new MovieDBHelper(getContext());
return true;
}
public static UriMatcher buildUriMatcher(){
String content = MovieContract.CONTENT_AUTHORITY;
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(content, MovieContract.PATH_GENRE, GENRE);
matcher.addURI(content, MovieContract.PATH_GENRE + "/#", GENRE_ID);
matcher.addURI(content, MovieContract.PATH_MOVIE, MOVIE);
matcher.addURI(content, MovieContract.PATH_MOVIE + "/#", MOVIE_ID);
return matcher;
}
@Override
public String getType(Uri uri) {
switch(sUriMatcher.match(uri)){
case GENRE:
return MovieContract.GenreEntry.CONTENT_TYPE;
case GENRE_ID:
return MovieContract.GenreEntry.CONTENT_ITEM_TYPE;
case MOVIE:
return MovieContract.MovieEntry.CONTENT_TYPE;
case MOVIE_ID:
return MovieContract.MovieEntry.CONTENT_ITEM_TYPE;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
Cursor retCursor;
switch(sUriMatcher.match(uri)){
case GENRE:
retCursor = db.query(
MovieContract.GenreEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
case GENRE_ID:
long _id = ContentUris.parseId(uri);
retCursor = db.query(
MovieContract.GenreEntry.TABLE_NAME,
projection,
MovieContract.GenreEntry._ID + " = ?",
new String[]{String.valueOf(_id)},
null,
null,
sortOrder
);
break;
case MOVIE:
retCursor = db.query(
MovieContract.MovieEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
case MOVIE_ID:
_id = ContentUris.parseId(uri);
retCursor = db.query(
MovieContract.MovieEntry.TABLE_NAME,
projection,
MovieContract.MovieEntry._ID + " = ?",
new String[]{String.valueOf(_id)},
null,
null,
sortOrder
);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long _id;
Uri returnUri;
switch(sUriMatcher.match(uri)){
case GENRE:
_id = db.insert(MovieContract.GenreEntry.TABLE_NAME, null, values);
if(_id > 0){
returnUri = MovieContract.GenreEntry.buildGenreUri(_id);
} else{
throw new UnsupportedOperationException("Unable to insert rows into: " + uri);
}
break;
case MOVIE:
_id = db.insert(MovieContract.MovieEntry.TABLE_NAME, null, values);
if(_id > 0){
returnUri = MovieContract.MovieEntry.buildMovieUri(_id);
} else{
throw new UnsupportedOperationException("Unable to insert rows into: " + uri);
}
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return returnUri;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int rows;
switch(sUriMatcher.match(uri)){
case GENRE:
rows = db.delete(MovieContract.GenreEntry.TABLE_NAME, selection, selectionArgs);
break;
case MOVIE:
rows = db.delete(MovieContract.MovieEntry.TABLE_NAME, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
if(selection == null || rows != 0){
getContext().getContentResolver().notifyChange(uri, null);
}
return rows;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int rows;
switch(sUriMatcher.match(uri)){
case GENRE:
rows = db.update(MovieContract.GenreEntry.TABLE_NAME, values, selection, selectionArgs);
break;
case MOVIE:
rows = db.update(MovieContract.MovieEntry.TABLE_NAME, values, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
if(rows != 0){
getContext().getContentResolver().notifyChange(uri, null);
}
return rows;
}
}
希望这对你有所帮助。
GitHub上的演示: https://github.com/androidessence/MovieDatabase
完整文章: https://guides.codepath.com/android/creating-content-providers
参考资料:
注意:我复制代码只是因为如果演示或文章链接将来可能会被删除。
query
,queryUsers
,queryUser
,queryGroups
,queryGroup
这就是内置联系人提供程序的工作方式。com.android.providers.contacts.ContactsProvider2.javahttps://github.com/android/platform_packages_providers_contactsprovider/blob/master/src/com/android/providers/contacts/ContactsProvider2.java - Alex