ContentProvider(内容提供者)是Android的四大组件之一,可以实现不同进程间的数据共享。在Android 源码系统中,像设置,联系人,多媒体等都使用到了ContentProvider。其实ContentProvider最终也是操作Sqlite数据库,实现数据的增删改查。接下来我们看看怎么使用。
android:authorities="com.psp.user.provider"
public class DBOpenHelper extends SQLiteOpenHelper {
//数据库名
private static final String DB_NAME = "user.db";
//表名
public static final String DB_TABLE_NAME = "user";
//数据可版本号
private static final int DB_VERSION = 1;
public DBOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建一张用户表
String sql_create_user = "CREATE TABLE IF NOT EXISTS "+DB_TABLE_NAME+"(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT,age TEXT)";
db.execSQL(sql_create_user);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
三、实现UserContentProvider类,在onCreate()方法中向数据库中插入一条数据。实现query和insert方法,其他方法不做探究。
public class UserContentProvider extends ContentProvider {
//授权,和AndroidManifest.xml中的保持一致
public static final String AUTHORITY = "com.psp.user.provider";
//匹配Uri的类
private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//设置ContentProvider的唯一标识,用于匹配不同的Uri
private static final int USER_INFO = 1;
private SQLiteDatabase mDb;
//初始化
static {
//若URI资源路径 = content://com.psp.user.provider/user ,则返回注册码USER_INFO
uriMatcher.addURI(AUTHORITY, "user", USER_INFO);
}
private Context mContext;
public UserContentProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int uri_code = uriMatcher.match(uri);
switch (uri_code) {
case USER_INFO:
mDb.insert(DBOpenHelper.DB_TABLE_NAME, null, values);
break;
default:
throw new RuntimeException("出错了!!");
// 向该表添加数据
}
// 当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)
mContext.getContentResolver().notifyChange(uri, null);
return uri;
}
@Override
public boolean onCreate() {
mContext = getContext();
mDb = new DBOpenHelper(getContext()).getReadableDatabase();
//初始化一条数据
ContentValues initialValues = new ContentValues();
initialValues.put("name","zhang san");
initialValues.put("age",18);
mDb.insert(DBOpenHelper.DB_TABLE_NAME,null,initialValues);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int result = uriMatcher.match(uri);
//查询数据
switch (result){
case USER_INFO:
return mDb.query(DBOpenHelper.DB_TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder, null);
default:
throw new RuntimeException("出错了!!");
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
throw new UnsupportedOperationException("Not yet implemented");
}
}
在MainActivity的布局文件中添加两个按钮,一个实现查询,一个实现插入。布局如下:
MainActivity的代码实现如下:
public class MainActivity extends AppCompatActivity {
//匹配uri和UserContentProvider中的保持一致
public static final Uri USER_CONTENT_URI = Uri.parse("content://com.psp.user.provider/user");
Button query_user;
Button insert_user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
query_user = findViewById(R.id.bt_querry_user_info);
insert_user = findViewById(R.id.bt_insert_user_info);
query_user.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
queryProviderData(MainActivity.this);
}
});
insert_user.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
insertProviderData(MainActivity.this,"li si",22);
}
});
}
//查询数据库
public static String queryProviderData(Context context) {
try {
Cursor cursor = context.getContentResolver().query(USER_CONTENT_URI,
new String[]{"_id", "name","age"}, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
Log.d("psp_log","_id= "+cursor.getInt(0)+"\n"+
"name="+cursor.getString(1)+"\n"+"age="+cursor.getInt(2));
Toast.makeText(context,"name="+cursor.getString(1)+"\n"+"age="+cursor.getInt(2),Toast.LENGTH_SHORT).show();
}
cursor.close();
}else {
Log.d("psp_log","snCursor = null" );
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//向数据库中插入数据
public static void insertProviderData(Context context,String name,int age) {
ContentValues userValues = new ContentValues();
userValues.put("name", name);
userValues.put("age", age);
context.getContentResolver().insert(USER_CONTENT_URI, userValues);
}
}
启动应用,点击查询按钮,看是否有一条初始化的“zhang san”的用户,打印结果:
01-05 10:00:45.610 28827-28827/com.psp.contentproviderdemo D/psp_log: _id= 1
name=zhang san
age=18
我们在点击插入按钮,再点击查询按钮,看看“li si”是否插入成功,打印结果:
01-05 10:29:48.343 29993-29993/com.psp.contentproviderdemo D/psp_log: _id= 1
name=zhang san
age=18
01-05 10:29:48.354 29993-29993/com.psp.contentproviderdemo D/psp_log: _id= 2
name=li si
age=22
打印结果说明数据操作是成功的。
GitHub地址:pshiping2014/ContentProviderDemo