Android ContentProvider的使用实例
Uri基础
Uri的四个组成部分:content://contacts/people/5
1)schema:已由Android固定设置为content://
2)authority:ContentProvider权限,在AndroidMenifest中设置权限
3)path:要操作的数据库表
4)Id:查询的关键字(可选字段)
Uri的匹配表示要查询的数据,对于单个数据查询,可直接使用Uri定位具体的资源位置,但当范围查询时就需要结合通配符的使用,Uri提供以下两种通配符:
1)*:匹配由任意长度的任何有效字符组成的字符串
2)#:匹配由任意长度的数字字符组成的字符串
ContentProvider使用
ContentProvider一般配合数据库共同使用,实现对外共享数据的目的,所以它需要对数据库的增删改查操作
UriMatcher的作用是在使用Uri操作数据库时,根据发起请求的Uri和配置好的uriMatcher确定本次操作的数据表
ContentObserver,内容观察者,采用观察者模式在存储的数据发生修改时自动触发回调
ContentProvider的使用是通过ContentResolver实例进行操作的,调用getContentResolver()获取ContentResolver实例,进而进行增改删查
权限
android:readPermission:提供程序范围读取权限
android:writePermission:提供程序范围写入权限
数据库provider
public class StudentsProvider extends ContentProvider {
static final String DATABASE_NAME = "College";
static final String STUDENTS_TABLE_NAME = "students";
static final int DATABASE_VERSION = 1;
// 数据库表中的字段
static final String _ID = "_id"; // 是从1开始计数
static final String NAME = "name";
static final String GRADE = "grade";
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(@Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(" CREATE TABLE " + STUDENTS_TABLE_NAME +
" (_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
" name TEXT NOT NULL, " +
" grade TEXT NOT NULL)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + STUDENTS_TABLE_NAME);
onCreate(db);
}
}
private SQLiteDatabase db;
static final String PROVIDER_NAME = "com.example.provider.College";
static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/students");
static final int STUDENTS = 1;
static final int STUDENT_ID = 2;
static final UriMatcher uriMatcher;
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME, "students", STUDENTS);
uriMatcher.addURI(PROVIDER_NAME, "students/#", STUDENT_ID);
}
private static HashMap<String, String> STUDENTS_PROJECTION_MAP;
@Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
return (db == null)? false:true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(STUDENTS_TABLE_NAME);
switch (uriMatcher.match(uri)) {
case STUDENTS:
qb.setProjectionMap(STUDENTS_PROJECTION_MAP);
break;
case STUDENT_ID:
qb.appendWhere( _ID + "=" + uri.getPathSegments().get(1));
break;
}
if (sortOrder == null || sortOrder == ""){
sortOrder = NAME;
}
Cursor c = qb.query(db, projection, selection, selectionArgs,null, null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
long rowID = db.insert(STUDENTS_TABLE_NAME, "", values); //返回添加后的id
if (rowID > 0) {
Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(_uri, null);
return _uri;
}
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)){
case STUDENTS:
count = db.delete(STUDENTS_TABLE_NAME, selection, selectionArgs);
break;
case STUDENT_ID:
String id = uri.getPathSegments().get(1);
count = db.delete( STUDENTS_TABLE_NAME, _ID + " = " + id +
(!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
break;
default:
break;
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)){
case STUDENTS:
count = db.update(STUDENTS_TABLE_NAME, values, selection, selectionArgs);
break;
case STUDENT_ID:
count = db.update(STUDENTS_TABLE_NAME, values, _ID + " = " + uri.getPathSegments().get(1) +
(!TextUtils.isEmpty(selection) ? " AND (" +selection + ')' : ""), selectionArgs);
break;
default:
break;
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
权限设置
<provider android:name="StudentsProvider"
android:authorities="com.example.provider.College" >
</provider>
activity操作数据库
public class MainActivity extends AppCompatActivity {
// provider uri地址是包括表名
private Uri studentUri = Uri.parse("content://com.example.provider.College/students");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 注册内容观察者ContentObserver
getContentResolver().registerContentObserver(studentUri, true, new MyObserver(new Handler()));
}
public void onClickAdd(View view) {
ContentValues values = new ContentValues();
values.put(StudentsProvider.NAME, ((EditText)findViewById(R.id.tvName)).getText().toString());
values.put(StudentsProvider.GRADE, ((EditText)findViewById(R.id.tvGrade)).getText().toString());
Uri uri = getContentResolver().insert(studentUri, values);
Toast.makeText(getBaseContext(), "onClickAdd", Toast.LENGTH_LONG).show();
}
// projection 是要查询的字段,是一个String[]类型,如果为null,则查询所有字段
// selection 是where子句
// selectionArgs 是where子句的参数
public void onClickQuery(View view) {
Cursor cursor = getContentResolver().query(studentUri, null, null, null, null);
while (cursor.moveToNext()){
int stuId = cursor.getInt(0);
String vName = cursor.getString(cursor.getColumnIndex("name"));
String vGrade = cursor.getString(cursor.getColumnIndex("grade"));
}
cursor.close();
Toast.makeText(getBaseContext(), "onClickQuery", Toast.LENGTH_LONG).show();
}
public void onClickDelete(View view) {
getContentResolver().delete(studentUri, "name=?", new String[]{"xyz"});
Toast.makeText(getBaseContext(), "onClickDelete", Toast.LENGTH_LONG).show();
}
public void onClickUpdate(View view) {
Uri uri = ContentUris.withAppendedId(studentUri, 1);
Log.d("yy", "onClickUpdate, uri = " + uri);
ContentValues values = new ContentValues();
values.put(StudentsProvider.NAME, "xyz");
getContentResolver().update(uri, values, null, null);
Toast.makeText(getBaseContext(), "onClickUpdate", Toast.LENGTH_LONG).show();
}
// 监听数据库的类
private final class MyObserver extends ContentObserver {
public MyObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
Log.d("yy", "onChange, uri = " + uri);
Cursor cursor = getContentResolver().query(studentUri, null, null, null, null);
while (cursor.moveToNext()){
int stuId = cursor.getInt(0);
String vName = cursor.getString(cursor.getColumnIndex("name"));
String vGrade = cursor.getString(cursor.getColumnIndex("grade"));
Log.d("yy", "onChange, id = " + stuId + ", name = " + vName + ", grade = " + vGrade);
}
cursor.close();
}
}
}
<Button
android:id="@+id/btnUpdate"
android:text="更新"
android:onClick="onClickUpdate" />
上一篇: php跨平台运行什么意思
下一篇: Android的SQLite使用实例
推荐阅读
-
Android项目中使用HTTPS配置的步骤详解
-
Android使用AudioRecord实现暂停录音功能实例代码
-
Android下拉刷新PtrFrameLayout的使用实例代码
-
详解 android 光线传感器 light sensor的使用
-
使用JSP制作一个超简单的网页计算器的实例分享
-
使用Python的urllib和urllib2模块制作爬虫的实例教程
-
Android开发中button按钮的使用及动态添加组件方法示例
-
Android 中CheckBox的isChecked的使用实例详解
-
Android获取arrays.xml里的数组字段值实例详解
-
Android原生视频播放VideoView的使用