Android ContentProvider使用详解

Content Provider

Content Provider的几个抽象方法:

Query(Uri,String[],String,String[],String)查询

Insert(Uri,ContentValues)插入

UpdateUri,ContentValues,String,String[])更新

Delete(UriStringString[]);

getType(Uri);获得MIME数据类型

 

ContentResolver

ContentResolver中提供和ContentProvider中对应的方法,我们是间接的通过操作ContentResolver来操作ContentProvider,一般情况下,ContentProvider是单实例的,而ContentResolver可以有多个

 

URI

ContentProvider是通过URI来共享其数据。一个URI必须以“content://”开头接下来是URI授权的部分,这部分内容与AndroidManifest.xml配置文件中声明的授权内容一致,后面还可能有数据类型和记录ID

 

查询系统ContentProvider内容

步骤:

1.       通过对应getContentResolver()方法,获取ContentResolver对象。

2.       获取ContentProviderURI标示

3.       列出想要查询的URI标示

4.       调用ContentResolverquery方法来执行查询。

 

 

添加系统ContentProvider内容

步骤:

5.       通过对应getContentResolver()方法,获取ContentResolver对象。

6.       获取ContentProviderURI标示

7.       把添加的信息封装到ContentValues对象中

8.       调用ContentResolverinsert方法来执行添加

9.        

自定义ContentProvider

创建ContentProvider的步骤:

1.       创建保存数据的文件或数据库

2.       定义一个类继承ContentProvider,实现其抽象方法

3.       将定义好的ContentProviderAndroidMainfest.xml配置文件中声明,以便使用。

 下面开始代码实例:

 1package com.king.android.controls;

 2 
 3 import android.net.Uri;
 4 import android.provider.BaseColumns;
 5 
 6 /**
 7 
 8  * 描述:实体类。
 9  * 作者:Andy.Liu
10  * 时间: 2012-7-20  上午08:19:51
11  **/
12 public class Employees {
13     // 授权常量
14     public static final String AUTHORITY = "com.king.provider.Employees";
15     private Employees() {}
16     // 内部类
17     public static final class Employee implements BaseColumns {
18         // 构造方法
19         private Employee() {}
20         // 访问Uri
21         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/employee");
22         // 内容类型
23         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.king.employees";
24         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.king.employees";
25         
26         // 默认排序常量
27         public static final String DEFAULT_SORT_ORDER = "name DESC";// 按姓名排序
28         // 表字段常量
29         public static final String NAME = "name";                    // 姓名
30         public static final String GENDER= "gender";                // 性别
31         public static final String AGE = "age";                     // 年龄
32     }
33 
34 }

 数据库创建:

  1 package com.king.android.controls;

 2 
 3 import android.content.Context;
 4 import android.database.sqlite.SQLiteDatabase;
 5 import android.database.sqlite.SQLiteOpenHelper;
 6 
 7 import com.king.android.controls.Employees.Employee;
 8 
 9 /**
10 
11  * 描述:数据库操作工具类
12  * 作者:Andy.Liu
13  * 时间: 2012-7-20  上午08:22:54
14  **/
15 public class DBHelper extends SQLiteOpenHelper {
16     private static final String DATEBASE_NAME = "Employee.db";
17     private static final int DATAVASE_VERSION = 1;
18     public static final String EMPLOYEE_TABLE_NAME = "employee";
19     private static final String EMPLOYEE_TABLE_CREATE = "CREATE TABLE "
20             + EMPLOYEE_TABLE_NAME + " (" + Employee._ID
21             + " INTEGER PRIMARY KEY," + Employee.NAME + " TEXT,"
22             + Employee.GENDER + " TEXT," + Employee.AGE + " INTEGER" + ")";
23 
24     //创建数据库
25     public DBHelper(Context context) {
26         super(context, DATEBASE_NAME, null, DATAVASE_VERSION);
27         
28     }
29 
30     @Override//创建时调用
31     public void onCreate(SQLiteDatabase db) {
32         db.execSQL(EMPLOYEE_TABLE_CREATE);
33     }
34 
35     @Override//版本更新时调用
36     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
37         db.execSQL("DROP TABLE IF EXISTS "+ EMPLOYEE_TABLE_NAME);
38         onCreate(db);
39     }
40 
41 }

  

创建EmployeeProvider ,待续。。。。 package com.king.android.controls;


import java.util.HashMap;

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.text.TextUtils;

import com.king.android.controls.Employees.Employee;

/**

 * 描述:ContentProvider具体使用
 * 作者:Andy.Liu
 * 时间: 2012-7-20  上午08:39:26
 *
*/
public class EmployeeProvider extends ContentProvider {
    
    private DBHelper mDBHelper;
    //Uri工具类
    private static  UriMatcher sUriMather = null;
    
    //查询更新条件
    private static final int EMPLOYEE = 1;
    private static final int EMPLOYEE_ID = 2;
    
    //查询列集合
    private static HashMap<String,String> empProjectionMap;
    
    static{
        sUriMather = new UriMatcher(UriMatcher.NO_MATCH);
        sUriMather.addURI(Employees.AUTHORITY, "employee", EMPLOYEE);
        sUriMather.addURI(Employees.AUTHORITY, "employee/#", EMPLOYEE_ID);
        
        //实例化查询列集合
        empProjectionMap= new HashMap<String, String>();
        
        //添加查询列
        empProjectionMap.put(Employee._ID, Employee._ID);
        empProjectionMap.put(Employee.NAME, Employee.NAME);
        empProjectionMap.put(Employee.GENDER, Employee.GENDER);
        empProjectionMap.put(Employee.AGE, Employee.AGE);
    }

    @Override
    public boolean onCreate() {
        mDBHelper = new DBHelper(getContext());
        return true;
    }
    
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        //添加数据库实例
        SQLiteDatabase db = mDBHelper.getWritableDatabase();
        //插入数据,返回行ID
        long rowId = db.insert(DBHelper.EMPLOYEE_TABLE_NAME, Employee.NAME, values);
        //如果插入成功后返回Uri
        if(rowId>0){
            Uri empUri = ContentUris.withAppendedId(Employee.CONTENT_URI, rowId);
            getContext().getContentResolver().notifyChange(empUri, null);
            return empUri;
        }
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        //添加数据库实例
        SQLiteDatabase db = mDBHelper.getWritableDatabase();
        
        int count;
        
        switch(sUriMather.match(uri)){
        case EMPLOYEE:
            count = db.delete(DBHelper.EMPLOYEE_TABLE_NAME, selection, selectionArgs);
            break;
        case EMPLOYEE_ID:
            String noteId = uri.getPathSegments().get(1);
            count = db.delete(DBHelper.EMPLOYEE_TABLE_NAME, Employee._ID + "="+noteId+(!TextUtils.isEmpty(selection)?" AND ("+selection+')':""), selectionArgs);
            break;
            default:
                throw new IllegalArgumentException("错误的Uri "+uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public String getType(Uri uri) {

        return null;
    }


    @Override
    public Cursor query(Uri uri, String[] projection, String selection,    String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        switch(sUriMather.match(uri)){
        //查询所有
        case EMPLOYEE:
            qb.setTables(DBHelper.EMPLOYEE_TABLE_NAME);
            qb.setProjectionMap(empProjectionMap);
            break;
            
            //根据ID查询
        case EMPLOYEE_ID:
            qb.setTables(DBHelper.EMPLOYEE_TABLE_NAME);
            qb.setProjectionMap(empProjectionMap);
            qb.appendWhere(Employee._ID+"="+uri.getPathSegments().get(1));
            break;
        default:
            throw new IllegalArgumentException("错误的Uri "+uri);
        }
        //使用默认排序
        String orderBy;
            if(TextUtils.isEmpty(sortOrder)){
                orderBy = Employee.DEFAULT_SORT_ORDER;
            }else{
                orderBy = sortOrder;
            }
            
            //获得数据库实例
            SQLiteDatabase db = mDBHelper.getReadableDatabase();
            //返回游标集合
            Cursor c = qb.query(db, projection, selection, selectionArgs, nullnull, sortOrder);
            c.setNotificationUri(getContext().getContentResolver(), uri);
            return c;
    }

    //更新方法
    @Override
    public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
        
        //添加数据库实例
        SQLiteDatabase db = mDBHelper.getWritableDatabase();
        
        int count;
        
        switch(sUriMather.match(uri)){
        case EMPLOYEE:
            count = db.update(DBHelper.EMPLOYEE_TABLE_NAME,values, selection, selectionArgs);
            break;
        case EMPLOYEE_ID:
            String noteId = uri.getPathSegments().get(1);
            count = db.update(DBHelper.EMPLOYEE_TABLE_NAME,values, Employee._ID + "="+noteId+(!TextUtils.isEmpty(selection)?" AND ("+selection+')':""), selectionArgs);
            break;
            default:
                throw new IllegalArgumentException("错误的Uri "+uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

}

测试部分:package com.king.android.controls;


import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.king.android.R;
import com.king.android.controls.Employees.Employee;

/**

 * 描述:测试Content Provider
 * 作者:Andy.Liu
 * 时间: 2012-7-22  下午04:46:19
 *
*/
public class ProviderActivity extends Activity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        insert();
        query();
        update();
        query();
        delete();
        query();
        
    }
    
    private void delete(){
        //删除ID为1的记录
        Uri uri = ContentUris.withAppendedId(Employee.CONTENT_URI, 1);
        //获得ContentResolver,并删除
        getContentResolver().delete(uri, nullnull);
    }
    
    private void update(){
        //更新ID为1的记录
        Uri uri = ContentUris.withAppendedId(Employee.CONTENT_URI, 1);
        ContentValues cv = new ContentValues();
        cv.put(Employee.NAME, "king.liu");
        cv.put(Employee.GENDER, "male");
        cv.put(Employee.AGE, 50);
        getContentResolver().update(uri, cv, nullnull);
    }
    
    private void query(){
        //查询列数据
        String[] projeciton = new String[]{
                Employee._ID,
                Employee.NAME,
                Employee.GENDER,
                Employee.AGE,
        };
        
        //查询所有备忘录信息
        Cursor c =managedQuery(Employee.CONTENT_URI, projeciton, nullnull, Employee.DEFAULT_SORT_ORDER);
        
        //判断是否为空
        if(c.moveToFirst()){
            //遍历游标
            for(int i = 0;i<c.getCount();i++){
                c.moveToPosition(i);
                //获得姓名
                String name = c.getString(1);
                String gender = c.getString(2);
                int age = c.getInt(3);
                Log.i("provider", name+":"+gender+":"+age);
                Toast.makeText(ProviderActivity.this, "输出:name:=="+name+"gender=="+gender+"age=="+age, Toast.LENGTH_LONG).show();
            }
        }
        
    }
    private void insert(){
        //更新ID为1的记录
        Uri uri = Employee.CONTENT_URI;
        ContentValues cv = new ContentValues();
        cv.put(Employee.NAME, "king.liu");
        cv.put(Employee.GENDER, "male");
        cv.put(Employee.AGE, 20);
        getContentResolver().insert(uri, cv);
    }

}

 注意:注册使用provider一定要在AndroidManifest.xml注册:

   <!--begin Content Provider -->
                <provider android:name=".controls.EmployeeProvider" android:authorities="com.king.provider.Employees"/>

              <!--end Content Provider --> 

运行效果如下: 

 

原文地址:https://www.cnblogs.com/liuzenglong/p/2600489.html