ContentProvider

ContentProvider

ContentProvider是Andorid的四大组件之一,它封装了数据库的底层实现暴露接口和ContentResolver一起组成的Andorid系统中通用数据存储 查询 修改 删除 方式。同时支持应用间数据交换是它最大的优势。

下面就用一个简答的例子来展示一下ContentProvider的简单实用。

  1. DbHelper.java
    数据库帮助类,创建 更新数据库的最佳实践、
package com.view.loaders.db;

import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DbHelper extends SQLiteOpenHelper {
    // 數據庫的名字,sqlite基於文件,所以要帶後綴名.db
    private static final String name = "myDb.db";
    // 數據庫的版本號
    private static int version = 1;
    // person 表的表名 public 暴露
    public static final String DATABASE_PERSON_TABLE = "person";

    public DbHelper(Context context) {
        super(context, name, null, version);
        // TODO Auto-generated constructor stub
    }

    /**
     * 创建数据库,执行建表语句
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "create table person (id integer primary key autoincrement,name varchar(64),password varchar(16));";
        db.execSQL(sql);
    }

    /**
     * 當版本號改變是,會條用此方法
     */
    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
        // TODO Auto-generated method stub

    }

}

2.PersonContentProvider.java

ContentProvider类,实现以下几个方法

The primary methods that need to be implemented are:
- onCreate() which is called to initialize the provider
- query(Uri, String[], String, String[], String) which returns data to the caller 
- insert(Uri, ContentValues) which inserts new data into the content provider 
- update(Uri, ContentValues, String, String[]) which updates existing data in the content provider 
- delete(Uri, String, String[]) which deletes data from the content provider 
- getType(Uri) which returns the MIME type of data in the content provider 
package com.view.loaders.provider;

import com.view.loaders.db.DbHelper;

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.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.util.Log;
import android.widget.SeekBar;

public class PersonContentProvider extends ContentProvider {
    // 公开的 内容uri
    // uri 通常只有两种格式,即请求全数据的 还有 withAppendId (/#)形式的

    public static final Uri Content_URI = Uri
            .parse("content://com.view.loaders.provider.PersonContentProvider/person");
    // 列名很重要 ,公开查询的ID 和其他列的列名
    public static final String KEY_ID = "id";
    public static final String COLUMN_1_NAME = "name";
    public static final String COLUMN_2_NAME = "password";

    // 数据库帮助类
    private DbHelper helper;
    // 单行操作 还是多行操作
    private static final int SINGLE_ROW = 2;
    private static final int ALLROWS = 1;

    private static final UriMatcher URI_MATCHER = new UriMatcher(
            UriMatcher.NO_MATCH);

    static {
        // 匹配
        // 单行操作 多行操作授权相同,主要是路径不同

        URI_MATCHER.addURI("com.view.loaders.provider.PersonContentProvider",
                "person/#", SINGLE_ROW);
        URI_MATCHER.addURI("com.view.loaders.provider.PersonContentProvider",
                "person", ALLROWS);
    }

    public PersonContentProvider() {
        // TODO Auto-generated constructor stub
    }

    /**
     * 初始化 在此实例化数据库帮助类
     */
    @Override
    public boolean onCreate() {
        helper = new DbHelper(getContext());
        return true;
    }

    /**
     * 返回MIME信息
     */
    @Override
    public String getType(Uri uri) {
        int flag = URI_MATCHER.match(uri);
        Log.i("nikan", "11111------" + flag);
        switch (flag) {
        case SINGLE_ROW:
            return "vnd.android.cursor.item/person";

        case ALLROWS:
            return " vnd.android.cursor.dir/person";

        }
        return null;
    }

    /**
     * 插入
     */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        SQLiteDatabase db = helper.getWritableDatabase();
        Uri newUri = null;

        int flag = URI_MATCHER.match(uri);
        Log.i("nikan", "insert   ......." + flag);
        // 插入的Uri不带id,id为自动增长
        // 所以插入的Uri会匹配为ALLROWS,或者不需要匹配验证
        switch (flag) {
        case ALLROWS:
            Log.i("nikan", "insert   0002  .......");
            long id = db.insert("person", null, values);
            newUri = ContentUris.withAppendedId(uri, id);
            Log.i("nikan", newUri.toString());
            return newUri;

        default:
            break;
        }
        return null;
    }

    /**
     * 删除
     */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int flag = URI_MATCHER.match(uri);
        SQLiteDatabase db = helper.getWritableDatabase();
        switch (flag) {
        case SINGLE_ROW:
            // String rowID=uri.getPathSegments().get(1);
            // 获取Uri里面的ID
            long id = ContentUris.parseId(uri);
            String whereValues = "id=" + id;
            Log.i("nikan", "delete   ......." + id);
            // 如果selection不为空,添加where条件
            if (selection != null && "".equals(selection.trim())) {
                whereValues += "AND" + selection;
            }
            int count = db.delete("person", whereValues, selectionArgs);
            // count 删除操作影响的行数
            if (count > 0) {
                Log.i("nikan", "delete success   .......");
            }

            return count;

        case ALLROWS:
            int counts = db.delete("person", selection, selectionArgs);
            return counts;

        default:
            return 0;
        }

    }

    /**
     * 更新数据
     */
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        int flag = URI_MATCHER.match(uri);
        SQLiteDatabase db = helper.getWritableDatabase();
        switch (flag) {
        case SINGLE_ROW:
            long id = ContentUris.parseId(uri);
            String whereValues = "id=" + id;
            if (selection != null && "".equals(selection.trim())) {
                whereValues += "AND" + selection;
            }
            int count = db.update("person", values, whereValues, selectionArgs);
            if (count > 0) {
                Log.i("nikan", "update success....." + id);
                return count;
            }

        default:
            break;
        }
        return 0;
    }

    /**
     * 查询
     */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = helper.getWritableDatabase();
        // SQLiteQueryBuilder is a helper class that creates the
        // proper SQL syntax for us.
        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();

        // Set the table we're querying.
        qBuilder.setTables(DbHelper.DATABASE_PERSON_TABLE);

        // If the query ends in a specific record number, we're
        // being asked for a specific record, so set the
        // WHERE clause in our query.
        if ((URI_MATCHER.match(uri)) == SINGLE_ROW) {
            qBuilder.appendWhere("id=" + ContentUris.parseId(uri));
        }

        // Make the query.
        Cursor c = qBuilder.query(db, projection, selection, selectionArgs,
                null, null, sortOrder);
        // 通知所有觀察者 ,數據集以改變
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;

    }

}

3.在清单文件注册ContentProvider

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.view.loaders"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="19" />

    <instrumentation 
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.view.loaders"></instrumentation>
    <!--  添加读取联系人的权限-->
    <uses-permission android:name="android.permission.READ_CONTACTS"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <uses-library android:name="android.test.runner" >
        </uses-library>

        <activity
            android:name="com.view.loaders.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--看这里 看这里 看这里-->
        <!-- 注册一个contentProvier -->
        <provider
            android:name="com.view.loaders.provider.PersonContentProvider"
            android:authorities="com.view.loaders.provider.PersonContentProvider" >
        </provider>

    </application>

</manifest>

4.MyTest.java

测试类,测试增删改查

package com.view.loaders.test;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;

import com.view.loaders.db.DbHelper;
import com.view.loaders.provider.PersonContentProvider;

public class MyTest extends AndroidTestCase {

    public MyTest() {
        // TODO Auto-generated constructor stub
    }

    public void TestCreate() {
        DbHelper helper = new DbHelper(getContext());
        helper.getWritableDatabase();
    }

    public void TestInsert() {

        ContentResolver contentResolver = getContext().getContentResolver();
        ContentValues values = new ContentValues();
        values.put("name", "ride on side");
        values.put("password", "you are mine");
        Uri uri = PersonContentProvider.Content_URI;
        Log.i("nikan", uri.toString() + "    ------>");
        contentResolver.insert(uri, values);

    }

    public void TestDelete() {
        ContentResolver contentResolver = getContext().getContentResolver();
        Uri uri = ContentUris.withAppendedId(PersonContentProvider.Content_URI,
                1);
        contentResolver.delete(uri, null, null);
    }

    public void TestUpdate() {
        ContentResolver contentResolver = getContext().getContentResolver();
        Uri uri = ContentUris.withAppendedId(PersonContentProvider.Content_URI,
                2);
        ContentValues values = new ContentValues();
        // values.put("name", "RainBow");

        values.put("password", "22222");
        contentResolver.update(uri, values, null, null);
    }

    public void TestQuery() {
        ContentResolver contentResolver = getContext().getContentResolver();
        // 指定ID,單行查詢
        /*
         * Uri uri=ContentUris.withAppendedId(PersonContentProvider.Content_URI,
         * 2); Cursor cursor= contentResolver.query(uri, null, null, null,
         * null);
         */

        Cursor cursor = contentResolver.query(
                PersonContentProvider.Content_URI, null, null, null, null);
        while (cursor.moveToNext()) {
            String name = cursor.getString(cursor
                    .getColumnIndex(PersonContentProvider.COLUMN_1_NAME));
            String password = cursor.getString(cursor
                    .getColumnIndex(PersonContentProvider.COLUMN_2_NAME));
            Log.i("nikan", "<<<-----" + name + "------>>" + password);

        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值