ContentProvider为存储和读取数据提供了统一的接口,使用ContentProvider,应用程序可以实现数据共享,android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)。
本实例将SQLite作为存储数据的方式。
Activity代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content_provider);
insertButton = (Button) findViewById(R.id.insertButton);
updateButton = (Button) findViewById(R.id.updateButton);
deleteButton = (Button) findViewById(R.id.deleteButton);
queryButton = (Button) findViewById(R.id.queryButton);
insertButton.setOnClickListener(new InsertListener());
updateButton.setOnClickListener(new UpdateListener());
deleteButton.setOnClickListener(new DeleteListener());
queryButton.setOnClickListener(new QueryListener());
}
class InsertListener implements OnClickListener {
@Override
public void onClick(View v) {
ContentValues[] values = new ContentValues[2];
ContentValues value = new ContentValues();
value.put(CPMetadata.users.NAME, "张三");
value.put(CPMetadata.users.AGE, 12);
values[0] = value;
value = new ContentValues();
value.put(CPMetadata.users.NAME, "李四");
value.put(CPMetadata.users.AGE, 11);
values[1] = value;
//多条插入,调用DemoProvider的insert(),每条调用一次,结果返回成功行数
int count = getContentResolver().bulkInsert(CPMetadata.users.CONTENT_URI, values);
// 插入单条数据
// Uri uri =
// getContentResolver().insert(CPMetadata.users.CONTENT_URI, values);
// Log.d("ContentProvider", "uri : " + uri);
Log.d("ContentProvider", "count : " + count);
}
}
class UpdateListener implements OnClickListener {
@Override
public void onClick(View v) {
//要更新的数据
ContentValues values = new ContentValues();
values.put(CPMetadata.users.NAME, "赵六");
values.put(CPMetadata.users.AGE, 22);
//根据ID更新,ContentUris.withAppendedId() 方法在URI的结尾追加一个1
Uri uri = ContentUris.withAppendedId(CPMetadata.users.CONTENT_URI, 1);
int count = getContentResolver().update(uri, values, null, null);
Log.d("ContentProvider", "update rows : " + count);
}
}
class DeleteListener implements OnClickListener {
@Override
public void onClick(View v) {
//根据ID删除,ContentUris.withAppendedId() 方法在URI的结尾追加一个2
Uri uri = ContentUris.withAppendedId(CPMetadata.users.CONTENT_URI, 2);
int count = getContentResolver().delete(uri, null, null);
Log.d("ContentProvider", "delete rows : " + count);
}
}
class QueryListener implements OnClickListener {
@Override
public void onClick(View v) {
//根据ID查询使用此uri,ContentUris.withAppendedId() 方法在URI的结尾追加一个1
//Uri uri = ContentUris.withAppendedId(CPMetadata.users.CONTENT_URI, 1);
//更新和删除数据使用where子句方法同理
Cursor cursor = getContentResolver().query(CPMetadata.users.CONTENT_URI, null
, CPMetadata.users.NAME + "=?", new String[]{"张三"}, CPMetadata.users._ID + " desc");
//根据游标打印查询结果
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(CPMetadata.users._ID));
String name = cursor.getString(cursor.getColumnIndex(CPMetadata.users.NAME));
String age = cursor.getString(cursor.getColumnIndex(CPMetadata.users.AGE));
Log.d("ContentProvider", "ID : " + id + " NAME : " + name + " AGE : " + age);
}
cursor.close();
}
}
CPMetadata代码:
public class CPMetadata {
public static final String AUTHORITY = "com.example.olds1_contentprovider.DemoProvider";
public static final String DATABASE_NAME = "DemoProviderDB";
public static final int DATABASE_VERSION = 1;
public static final int CONTENT = 1;
public static final int CONTENT_ITEM = 2;
public static final class users implements BaseColumns {
public static final String TABLE_NAME = "users";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/users");
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.demoprovider.user";
public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.demoprovider.user";
public static final String NAME = "name";
public static final String AGE = "age";
}
}
DBHelper代码:
public class DBHelper extends SQLiteOpenHelper{
public DBHelper(Context context) {
super(context, CPMetadata.DATABASE_NAME, null, CPMetadata.DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
StringBuffer sql = new StringBuffer();
sql.append("create table " + CPMetadata.users.TABLE_NAME + "(");
sql.append(CPMetadata.users._ID + " integer primary key autoincrement,");
sql.append(CPMetadata.users.NAME + " varchar(20),");
sql.append(CPMetadata.users.AGE + " integer);");
db.execSQL(sql.toString());
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
public class DemoProvider extends ContentProvider {
private DBHelper helper;
private SQLiteDatabase db;
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(CPMetadata.AUTHORITY, CPMetadata.users.TABLE_NAME, CPMetadata.CONTENT);
uriMatcher.addURI(CPMetadata.AUTHORITY, CPMetadata.users.TABLE_NAME + "/#",
CPMetadata.CONTENT_ITEM);
}
@Override
public boolean onCreate() {
helper = new DBHelper(getContext());
db = helper.getWritableDatabase();
return true;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case CPMetadata.CONTENT:
return CPMetadata.users.CONTENT_TYPE;
case CPMetadata.CONTENT_ITEM:
return CPMetadata.users.CONTENT_TYPE_ITEM;
default:
throw new IllegalArgumentException("unknown URI:" + uri);
}
}
/**
* 整理where子句
* 条件分为有ID和无ID两种,ID为主键具有唯一性,不用添加其他条件
* 无ID则使用传入的条件处理
* @param uri
* @param selection
* @return
*/
public String getWhereStr(Uri uri, String selection){
String whereStr;
switch (uriMatcher.match(uri)) {
case CPMetadata.CONTENT:
whereStr = selection;
break;
case CPMetadata.CONTENT_ITEM:
whereStr = CPMetadata.users._ID + "=" + uri.getPathSegments().get(1);
break;
default:
throw new IllegalArgumentException("unknown URI :" + uri);
}
return whereStr;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowid = db.insert(CPMetadata.users.TABLE_NAME, null, values);
if (rowid > 0) {
Uri insertUri = ContentUris.withAppendedId(CPMetadata.users.CONTENT_URI, rowid);
getContext().getContentResolver().notifyChange(insertUri, null);
Log.d("ContentProvider", "Insert Success :" + insertUri);
return insertUri;
}
throw new IllegalArgumentException("unknown URI: " + uri);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
String whereStr = getWhereStr(uri, selection);
Log.d("ContentProvider", "Delete Where :" + whereStr);
count = db.delete(CPMetadata.users.TABLE_NAME, whereStr, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int count = 0;
String whereStr = getWhereStr(uri, selection);
Log.d("ContentProvider", "Update Where :" + whereStr);
count = db.update(CPMetadata.users.TABLE_NAME, values, whereStr, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
Cursor cursor;
String whereStr = getWhereStr(uri, selection);
Log.d("ContentProvider", "Query Where :" + whereStr);
cursor = db.query(CPMetadata.users.TABLE_NAME, projection, whereStr, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
注册ContentProvider,
android:exported="true"
表示是否允许外部应用访问,必须设置
<provider
android:name="DemoProvider"
android:authorities="com.example.olds1_contentprovider.DemoProvider"
android:exported="true">
</provider>
新建一个test工程,
效果:
Activity代码如下:
private Button button;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
textView = (TextView)findViewById(R.id.textView);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String uriStr = "content://com.example.olds1_contentprovider.DemoProvider/users";
Uri uri = Uri.parse(uriStr);
Cursor cursor = getContentResolver().query(uri, null, "name=?", new String[]{"张三"}, null);
StringBuffer show = new StringBuffer();
//根据游标打印查询结果
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String age = cursor.getString(cursor.getColumnIndex("age"));
show.append("ID : " + id + " NAME : " + name + " AGE : " + age + "\n");
}
cursor.close();
textView.setText(show.toString());
}
});
}
完整代码下载地址: