1)创建合同类
合同类定义用于帮助应用程序处理内容提供者的内容URI,列名,意图动作和其他功能的常量。提供商不自动包含合同类别;提供者的开发人员必须定义它们,然后将其提供给其他开发人员。
提供者通常只有一个权限,即作为其Android内部名称的权限。为避免与其他提供程序发生冲突,请使用唯一的内容授权。由于此建议也适用于Android软件包名称,因此您可以将提供者权限定义为包含提供者的软件包名称的扩展名。例如,如果您的Android软件包名称为com.example.appname,则应授予您的提供商权限com.example.appname.provider。
public class MyContract { public static final String CONTENT_AUTHORITY = "com.example.myApp"; public static final String PATH_DATATABLE = "dataTable"; public static final String TABLE_NAME = "dataTable"; }
内容URI是标识提供者中数据的URI。内容URI包括整个提供程序的符号名称(其权限)和指向表或文件的名称(路径)。可选的id部分指向表中的单个行。ContentProvider的每种数据访问方法都有一个内容URI作为参数。这使您可以确定要访问的表,行或文件。在合同类中定义它们。
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_DATATABLE).build(); // 定义表的所有列和所需的常用功能
2)创建助手类
助手类管理数据库的创建和版本管理。
public class DatabaseHelper extends SQLiteOpenHelper { // 数据库结构发生变化时增加版本 public static final int DATABASE_VERSION = 1; // 文件系统中数据库的名称,您可以选择任何形式 public static final String DATABASE_NAME = "weather.db"; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { //首次创建数据库时调用。这是 // 创建表和表的初始填充。 } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //在需要升级数据库时调用。实施 // 应该使用此方法删除表,添加表或执行其他任何操作 // 需要升级到新的架构版本。 } }
3)创建一个扩展ContentProvider类的类
public class MyProvider extends ContentProvider { public DatabaseHelper dbHelper; public static final UriMatcher matcher = buildUriMatcher(); public static final int DATA_TABLE = 100; public static final int DATA_TABLE_DATE = 101;
UriMatcher将权限和路径映射到整数值。该方法match()返回URI的唯一整数值(可以是任意数字,只要它是唯一的)。switch语句在查询整个表和查询单个记录之间进行选择。如果URI是Table的Content URI,我们的UriMatcher返回100;如果URI指向该表中的特定行,则返回101。您可以使用#通配符来匹配任何数字并*匹配任何字符串。
public static UriMatcher buildUriMatcher() { UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(CONTENT_AUTHORITY, MyContract.PATH_DATATABLE, DATA_TABLE); uriMatcher.addURI(CONTENT_AUTHORITY,MyContract.PATH_DATATABLE+ "/#", DATA_TABLE_DATE); return uriMatcher; }
重要提示:addURI()呼叫顺序很重要!UriMatcher的显示顺序为:从第一个添加到最后一个。由于通配符喜欢#和*很贪婪,因此您需要确保正确订购了URI。例如:
uriMatcher.addURI(CONTENT_AUTHORITY, "/example", 1); uriMatcher.addURI(CONTENT_AUTHORITY, "/*", 2);
是正确的排序,因为匹配者/example在诉诸/*匹配之前会先查找。如果这些方法调用被反向调用并且您调用了uriMatcher.match("/example"),则UriMatcher一旦遇到/*路径,将停止寻找匹配项并返回错误结果!
然后,您将需要覆盖以下功能:
onCreate():初始化您的提供商。Android系统在创建您的提供程序后立即调用此方法。请注意,只有在ContentResolver对象尝试访问它之前,才创建您的提供程序。
@Override public boolean onCreate() { dbhelper = new DatabaseHelper(getContext()); return true; }
getType():返回与内容URI对应的MIME类型
@Override public String getType(Uri uri) { final int match = matcher.match(uri); switch (match) { case DATA_TABLE: returnContentResolver.CURSOR_DIR_BASE_TYPE+ "/" +MyContract.CONTENT_AUTHORITY+ "/" + MyContract.PATH_DATATABLE; case DATA_TABLE_DATE: returnContentResolver.ANY_CURSOR_ITEM_TYPE+ "/" +MyContract.CONTENT_AUTHORITY+ "/" + MyContract.PATH_DATATABLE; default: throw new UnsupportedOperationException("未知的Uri: " + uri); } }
query():从提供商处检索数据。使用参数选择要查询的表,要返回的行和列以及结果的排序顺序。将数据作为Cursor对象返回。
@Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor retCursor = dbHelper.getReadableDatabase().query( MyContract.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); retCursor.setNotificationUri(getContext().getContentResolver(), uri); return retCursor; }
在您的提供程序中插入新行。使用参数选择目标表并获取要使用的列值。返回新插入行的内容URI。
@Override public Uri insert(Uri uri, ContentValues values) { final SQLiteDatabase db = dbHelper.getWritableDatabase(); long id = db.insert(MyContract.TABLE_NAME, null, values); return ContentUris.withAppendedId(MyContract.CONTENT_URI, ID); }
delete():从提供商中删除行。使用参数选择表和要删除的行。返回删除的行数。
@Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase(); int rowsDeleted = db.delete(MyContract.TABLE_NAME, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); return rowsDeleted; }
update():更新提供商中的现有行。使用参数选择要更新的表和行并获取新的列值。返回更新的行数。
@Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase(); int rowsUpdated = db.update(MyContract.TABLE_NAME, values, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); return rowsUpdated; }
4)更新清单文件
<provider android:authorities="com.example.myApp" android:name=".DatabaseProvider"/>