Android数据储存之ContentProvider

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"/>

 运行效果:

 

猜你喜欢

转载自ch-kexin.iteye.com/blog/2355992