ContentProvider(内容提供者)是Android中的四大组件之一。主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对指定应用中的数据进行操作。ContentProvider分为系统的和自定义的,系统的也就是例如联系人,图片等数据。
总结:
1、ContentProvider为存储和读取数据提供了统一的接口
2、使用ContentProvider,应用程序可以实现数据共享
3、android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)
Uri介绍:
1、每一个ContentProvider都拥有一个公共的Uri,这个Uri用于表示这个ContentProvider提供的数据
2、Android所提供的ContentProvider都存放在Android.provider这个包里面
Android的ContentProvider URI有固定的形式:content://contract/people
前缀:固定为content : //
认证:contract 资源的唯一标识符
路径:people 具体的资源类型
A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;”content://”
B:URI 的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的 类名。这个标识在 元素的 authorities属性中说明:一般是定义该ContentProvider的包.类的名称;”content://hx.android.text.myprovider”
C:”content://hx.android.text.myprovider/tablename”路径,不知道是不是路径,通俗的讲就是你要操作的数据库中表的名字,或者你也可以自己定义,记得在使用的时候保持一致就ok了;
D:如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部; “content://hx.Android.text.myprovider/tablename/#” #表示数据id
在Android中广泛应用URI,而不是URL。URL标识资源的物理位置,相当于文件的路径;而URI则是标识资源的逻辑位置,并不提供资源的具体位置。比如说电话薄中的数据,如果用URL来标识的话,可能会是一个很复杂的文件结构,而且一旦文件的存储路径改变,URL也必须得改动。但是若是URI,则可以用诸如content://contract/people这样容易记录的逻辑地址来标识,而且并不需要关心文件的具体位置,即使文件位置改动也不需要做变化,当然这都是对于用户来说,后台程序中URI到具体位置的映射还是需要程序员来改动的。
ContentProvider提供的函数:
1、query() 查询
2、insert() 插入
3、update() 更新
4、delete() 删除
5、getType() 得到数据类型
6、onCreate() 创建时的回调函数
实现ContentProvider的过程:
1、定义一个COTENT_URI常量
2、定义一个类,继承ContentProvider
3、实现query(),delete(),update(),insert(),onCreate(),getType()方法
4、在AndroidMainfest.xml中申明
下面是一个使用ContentProvider进行CRUD操作的例子。
IProivderMetaData.java
package com.liuzhichao.privoder;
import android.net.Uri;
import android.provider.BaseColumns;
public interface IProivderMetaData {
// 定义外部访问的Authority
public static final String AUTHORITY = "com.liuzhichao.bookprovider";
// 数据库名称
public static final String DB_NAME = "book.db";
// 数据库版本
public static final int VERSION = 1;
public interface BookTableMetaData extends BaseColumns {
// 表名
public static final String TABLE_NAME = "book";
// 外部程序访问本表的uri地址
public static final Uri CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/" + TABLE_NAME);
// book表列名
public static final String BOOK_ID = "_id";
public static final String BOOK_NAME = "name";
public static final String BOOL_PUBLISHER = "publisher";
//默认排序
public static final String SORT_ORDER="_id desc";
//得到book表中的所有记录
public static final String CONTENT_LIST="vnd.android.cursor.dir/vnd.bookprovider.book";
//得到一个表信息
public static final String CONTENT_ITEM="vnd.android.cursor.item/vnd.bookprovider.book";
}
}
DBHelper.java
package com.liuzhichao.privoder;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBHelper extends SQLiteOpenHelper implements IProivderMetaData {
private static final String TAG = "DBHelper";
public DBHelper(Context context) {
super(context, DB_NAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String TABLESQL = "create table if not exists "
+ BookTableMetaData.TABLE_NAME + " ("
+ BookTableMetaData.BOOK_ID + " integer primary key,"
+ BookTableMetaData.BOOK_NAME + " varchar,"
+ BookTableMetaData.BOOL_PUBLISHER + " varchar)";
db.execSQL(TABLESQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + DB_NAME);
onCreate(db);
}
}
BookContentProvider.java
package com.liuzhichao.privoder;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
public class BookContentProvider extends ContentProvider {
private static final String TAG="BookContentProvider";
private static UriMatcher uriMatcher = null;
private static final int BOOKS = 1;
private static final int BOOK = 2;
private DBHelper dbHelper;
private SQLiteDatabase db;
/**
* 这部分就相当于为外部程序准备好一个所有地址匹配集合
*/
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(IProivderMetaData.AUTHORITY,
IProivderMetaData.BookTableMetaData.TABLE_NAME, BOOKS);
uriMatcher.addURI(IProivderMetaData.AUTHORITY,
IProivderMetaData.BookTableMetaData.TABLE_NAME+"/#", BOOK);
}
@Override
public boolean onCreate() {
dbHelper = new DBHelper(getContext());
return (dbHelper == null) ? false : true;
}
// 取得数据的类型,此方法会在系统进行URI的MIME过滤时被调用。
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case BOOKS:
return IProivderMetaData.BookTableMetaData.CONTENT_LIST;
case BOOK:
return IProivderMetaData.BookTableMetaData.CONTENT_ITEM;
default:
throw new IllegalArgumentException("This is a unKnow Uri"
+ uri.toString());
}
}
//增加
@Override
public Uri insert(Uri uri, ContentValues values) {
switch (uriMatcher.match(uri)) {
case BOOKS:
db = dbHelper.getWritableDatabase();//取得数据库操作实例
//执行添加,返回行号,如果主健字段是自增长的,那么行号会等于主键id
long rowId = db.insert(
IProivderMetaData.BookTableMetaData.TABLE_NAME,
IProivderMetaData.BookTableMetaData.BOOK_ID, values);
Uri insertUri = Uri.withAppendedPath(uri, "/" + rowId);
Log.i(TAG, "insertUri:"+insertUri.toString());
//发出数据变化通知(book表的数据发生变化)
getContext().getContentResolver().notifyChange(uri, null);
return insertUri;
default:
//不能识别uri
throw new IllegalArgumentException("This is a unKnow Uri"
+ uri.toString());
}
}
//查询
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
db = dbHelper.getReadableDatabase();
switch (uriMatcher.match(uri)) {
case BOOKS:
return db
.query(IProivderMetaData.BookTableMetaData.TABLE_NAME,
projection, selection, selectionArgs, null, null,
sortOrder);
case BOOK:
long id = ContentUris.parseId(uri);
String where = "_id=" + id;
if (selection != null && !"".equals(selection)) {
where = selection + " and " + where;
}
return db.query(IProivderMetaData.BookTableMetaData.TABLE_NAME, projection, where, selectionArgs, null,
null, sortOrder);
default:
throw new IllegalArgumentException("This is a unKnow Uri"
+ uri.toString());
}
}
//删除
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
db = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)) {
case BOOKS:
return db.delete(IProivderMetaData.BookTableMetaData.TABLE_NAME, selection, selectionArgs);
case BOOK:
long id = ContentUris.parseId(uri);
String where = "_id=" + id;
if (selection != null && !"".equals(selection)) {
where = selection + " and " + where;
}
return db.delete(IProivderMetaData.BookTableMetaData.TABLE_NAME, selection, selectionArgs);
default:
throw new IllegalArgumentException("This is a unKnow Uri"
+ uri.toString());
}
}
//更新
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
db = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)) {
case BOOKS:
return db.update(IProivderMetaData.BookTableMetaData.TABLE_NAME,
values, null, null);
case BOOK:
long id = ContentUris.parseId(uri);
String where = "_id=" + id;
if (selection != null && !"".equals(selection)) {
where = selection + " and " + where;
}
return db.update(IProivderMetaData.BookTableMetaData.TABLE_NAME,
values, selection, selectionArgs);
default:
throw new IllegalArgumentException("This is a unKnow Uri"
+ uri.toString());
}
}
}
ContentProviderDemoActivity.java
package com.liuzhichao.privoder;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class ContentProviderDemoActivity extends Activity {
private EditText et_bookId;
private EditText et_bookName;
private EditText et_bookPublisher;
private Button btn_add;
private Button btn_delete;
private Button btn_update;
private Button btn_query;
private Button btn_showall;
private Button btn_claer;
ContentResolver contentResolver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 取得ContentResolver对象
contentResolver = this.getContentResolver();
findViews();
}
void findViews() {
// 根据id获取组件
et_bookId = (EditText) findViewById(R.id.book_id);
et_bookName = (EditText) findViewById(R.id.book_name);
et_bookPublisher = (EditText) findViewById(R.id.book_publisher);
btn_add = (Button) findViewById(R.id.btn_add);
btn_delete = (Button) findViewById(R.id.btn_delete);
btn_update = (Button) findViewById(R.id.btn_update);
btn_query = (Button) findViewById(R.id.btn_query);
btn_showall = (Button) findViewById(R.id.btn_showall);
btn_claer = (Button) findViewById(R.id.btn_claer);
// 设置按钮单击事件处理
btn_add.setOnClickListener(ClickListener);
btn_delete.setOnClickListener(ClickListener);
btn_update.setOnClickListener(ClickListener);
btn_query.setOnClickListener(ClickListener);
btn_showall.setOnClickListener(ClickListener);
btn_claer.setOnClickListener(ClickListener);
}
// 按钮事件处理
private View.OnClickListener ClickListener = new OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_add:
long rowid = btnAddHandler();
Toast.makeText(getApplicationContext(), "数据增加成功,编号:" + rowid, 1)
.show();
break;
case R.id.btn_delete:
long deleteRow=btnDeleteHandler();
Toast.makeText(getApplicationContext(), "数据删除成功,删除了 "+deleteRow+" 行数据" , 1)
.show();
break;
case R.id.btn_update:
long updateRow=btnUpdateHandler();
Toast.makeText(getApplicationContext(), "数据更新成功,更新了 "+updateRow+" 行数据" , 1)
.show();
break;
case R.id.btn_query:
btnQueryHandler();
break;
case R.id.btn_showall:
startActivity(new Intent(getApplicationContext(), ShowAllBooksActivity.class));
break;
case R.id.btn_claer:
et_bookId.setText("");
et_bookName.setText("");
et_bookPublisher.setText("");
break;
default:
break;
}
}
};
/**
* 增加图书
*
* @return
*/
private long btnAddHandler() {
String bookname = et_bookName.getText().toString();
String bookPubliser = et_bookPublisher.getText().toString();
ContentValues values = new ContentValues();
values.put(IProivderMetaData.BookTableMetaData.BOOK_NAME, bookname);
values.put(IProivderMetaData.BookTableMetaData.BOOL_PUBLISHER,
bookPubliser);
Uri insertUri = contentResolver.insert(
IProivderMetaData.BookTableMetaData.CONTENT_URI, values);
return ContentUris.parseId(insertUri);
}
//删除
private long btnDeleteHandler() {
String bookId = et_bookId.getText().toString();
long row=0;
if (!"".equals(bookId) && bookId != null) {
ContentValues values = new ContentValues();
values.put(IProivderMetaData.BookTableMetaData.BOOK_ID, bookId);
//根据id删除
row= contentResolver.delete(
Uri.withAppendedPath(IProivderMetaData.BookTableMetaData.CONTENT_URI, bookId), "_id = ?",
new String[] {bookId});
} else {
//删除所有
row= contentResolver.delete(
IProivderMetaData.BookTableMetaData.CONTENT_URI, null,
null);
}
return row;
}
//修改
private long btnUpdateHandler() {
String bookId = et_bookId.getText().toString();
String bookname = et_bookName.getText().toString();
String bookPubliser = et_bookPublisher.getText().toString();
ContentValues values = new ContentValues();
//values.put(IProivderMetaData.BookTableMetaData.BOOK_ID, bookId);
values.put(IProivderMetaData.BookTableMetaData.BOOK_NAME, bookname);
values.put(IProivderMetaData.BookTableMetaData.BOOL_PUBLISHER,
bookPubliser);
long rowid=0;
if ("".equals(bookId) || bookId == null) {
//更新所有
rowid=contentResolver.update(
IProivderMetaData.BookTableMetaData.CONTENT_URI, values,
null, null);
}else{
//根据Id更新
rowid=contentResolver.update(
Uri.withAppendedPath(IProivderMetaData.BookTableMetaData.CONTENT_URI, bookId), values,
"_id = ? ", new String[]{bookid});
}
return rowid;
}
//查询(根据Id查询)
private void btnQueryHandler() {
String bookId = et_bookId.getText().toString();
ContentValues values = new ContentValues();
values.put(IProivderMetaData.BookTableMetaData.BOOK_ID, bookId);
Cursor cursor = contentResolver.query(
IProivderMetaData.BookTableMetaData.CONTENT_URI, null,
" _id = ?", new String[] { bookId }, null);
if (cursor.moveToNext()) {
et_bookName
.setText(cursor
.getString(
cursor.getColumnIndex(IProivderMetaData.BookTableMetaData.BOOK_NAME))
.toString());
et_bookPublisher
.setText(cursor
.getString(
cursor.getColumnIndex(IProivderMetaData.BookTableMetaData.BOOL_PUBLISHER))
.toString());
}
}
}
ShowAllBooksActivity.java
package com.liuzhichao.privoder;
import android.app.ListActivity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.SimpleCursorAdapter;
public class ShowAllBooksActivity extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(
IProivderMetaData.BookTableMetaData.CONTENT_URI, null, null,
null, null);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.list, cursor, new String[] {
IProivderMetaData.BookTableMetaData.BOOK_ID,
IProivderMetaData.BookTableMetaData.BOOK_NAME,
IProivderMetaData.BookTableMetaData.BOOL_PUBLISHER },
new int[] { R.id.book_id, R.id.book_name, R.id.book_publisher });
setListAdapter(adapter);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/bookid" />
<EditText
android:id="@+id/book_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/bookname" />
<EditText
android:id="@+id/book_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/bookpublisher" />
<EditText
android:id="@+id/book_publisher"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/btn_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/btn_add" />
<Button
android:id="@+id/btn_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/btn_delete" />
<Button
android:id="@+id/btn_update"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/btn_update" />
<Button
android:id="@+id/btn_query"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/btn_query" />
</LinearLayout>
<Button
android:id="@+id/btn_showall"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn_showall" />
<Button
android:id="@+id/btn_claer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn_clear" />
</LinearLayout>
activity_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/book_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:id="@+id/book_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:id="@+id/book_publisher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
不要忘了注册provider
<provider android:name=".BookContentProvider" android:authorities="com.liuzhichao.bookprovider"/>
运行效果: