Android 学习 笔记_06. Content Provider初步

1、作用:

     (1、为存储和获取(访问)数据提供了统一的接口(它对数据的存储进行了一层封装,让我们无需关心数据存储的细节就可以直接使用。)

     (2、能够让我们的数据在不同的应用程序中共享(SQLite只能在同一个应用程序中共享数据)

     (3、Android为常见的一些数据提供了Content Provider(包括了音频、视频、图片、通讯录等)

2、ContentProvider使用表的形式来组织数据

    

3、统一资源标识符 URL(为资源起名字)

     (1、每个ContentProvider都有一个公共的URl,用于表示该ContentProvider提供的数据

     (2、Android的ContentProvider都存放于android.provider包当中

4、ContentProvider函数:对数据进行增删改查的操作

      (1、query();

      (2、insert();

      (3、update();

      (4、delete();

      (5、getType();

      (6、onCreate();

5、实现ContentProvider的过程

      (1、定义一个CONTENT_URL常量

      (2、定义一个类,继承ContentProvider

      (3、实现上述函数方法

      (4、在Manifest.xml中声明

 

             

 CPActivity.java

 1 package zzl.contentprovider;
 2 
 3 import zzl.contentprovider.FirstProviderMetaData.UserTableMetaData;
 4 import android.app.Activity;
 5 import android.content.ContentValues;
 6 import android.database.Cursor;
 7 import android.net.Uri;
 8 import android.os.Bundle;
 9 import android.view.Menu;
10 import android.view.View;
11 import android.view.View.OnClickListener;
12 import android.widget.Button;
13 
14 public class CPActivity extends Activity {
15     
16     private Button insert=null;
17     private Button query=null;
18 
19     @Override
20     protected void onCreate(Bundle savedInstanceState) {
21         super.onCreate(savedInstanceState);
22         setContentView(R.layout.activity_cp);
23         
24         insert=(Button)findViewById(R.id.insert);
25         query=(Button)findViewById(R.id.query);
26         
27         insert.setOnClickListener(new InsertOnClickListener());
28         query.setOnClickListener(new QueryOnClickListener());
29         System.out.println(getContentResolver().getType(FirstProviderMetaData.UserTableMetaData.CONTENT_URI));
30     }
31     //往子表中插入一条记录
32     public class InsertOnClickListener implements OnClickListener{
33 
34         public void onClick(View arg0) {
35             // TODO Auto-generated method stub    
36             ContentValues values = new ContentValues();
37             values.put(FirstProviderMetaData.UserTableMetaData.USER_NAME, "tornadomeet");
38             //实际上使用的是ContentResolver的insert方法
39             //该insert中有2个参数,第一个为代表了ContentProvider的URL,第二个参数为要插入的值。此处的insert函数
40             //一执行,则自动调用ContentProvider的insert方法。
41             Uri uri = getContentResolver().insert(FirstProviderMetaData.UserTableMetaData.CONTENT_URI, 
42                     values);
43             System.out.println("uri--->" +uri.toString());
44         }        
45     }
46     
47     
48     //查询也是采用的ContentResolver中的query方法。
49     public class QueryOnClickListener implements OnClickListener{
50         public void onClick(View v) {
51             // TODO Auto-generated method stub        
52             Cursor c = getContentResolver().query(FirstProviderMetaData.UserTableMetaData.CONTENT_URI, 
53                     null, null, null, null);
54             while(c.moveToNext())
55                 System.out.println(c.getString(c.getColumnIndex(UserTableMetaData.USER_NAME)));
56         }     
57     }
58 
59     @Override
60     public boolean onCreateOptionsMenu(Menu menu) {
61         // Inflate the menu; this adds items to the action bar if it is present.
62         getMenuInflater().inflate(R.menu.activity_cp, menu);
63         return true;
64     }
65 
66 }

FirstProviderMetaData.java

 1 package zzl.contentprovider;
 2 
 3 import android.net.Uri;
 4 import android.provider.BaseColumns;
 5 
 6 public class FirstProviderMetaData {
 7 
 8     //这里的AUTHORTY为包的全名+ContentProvider子类的全名
 9     public static final String AUTHORTY = "zzl.contentprovider.FirstContentProvider";
10     //数据库名称
11     public static final String DATABASE_NAME = "FisrtProvider.db";
12     //数据库版本
13     public static final int DATABASE_VERSION = 1;
14     //数据库表名
15     public static final String USERS_TABLE_NAME = "users";
16     //表中的字表
17     public static final class UserTableMetaData implements BaseColumns{
18         
19         //子表名
20         public static final String TABLE_NAME = "users";
21         //访问ContentProvider的URL:CONTENT_URI为常量URL; parse是将文本转换成URL
22         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORTY + "/users");
23        
24         //返回ContentProvider中表的数据类型
25         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.firstprovider.user";
26         //返回ContentProvider表中item的一条数据类型
27         public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.firstprovider.user";
28         
29         //子表列名
30         public static final String USER_NAME = "name";
31         //表中记录的默认排序算法,这里是降序排列
32         public static final String DEFAULT_SORT_ORDER = "_id desc";
33         
34         
35     }
36     
37 }

FirstProviderMetaData.java

  1 package zzl.contentprovider;
  2 
  3 import java.util.HashMap;
  4 
  5 import zzl.contentprovider.FirstProviderMetaData.UserTableMetaData;
  6 import zzl.sqlite3.db.DatabaseHelper;
  7 import android.content.ContentProvider;
  8 import android.content.ContentUris;
  9 import android.content.ContentValues;
 10 import android.content.UriMatcher;
 11 import android.database.Cursor;
 12 import android.database.SQLException;
 13 import android.database.sqlite.SQLiteDatabase;
 14 import android.database.sqlite.SQLiteQueryBuilder;
 15 import android.net.Uri;
 16 import android.text.TextUtils;
 17 
 18 public class FirstContentProvider extends ContentProvider{
 19     
 20     //定义一个UriMatcher类对象,用来匹配URL:形成映射,规则是否合法
 21     public static final UriMatcher uriMatcher;
 22     //组时的ID
 23     public static final int INCOMING_USER_COLLECTION = 1;
 24     //单个时的ID
 25     public static final int INCOMING_USER_SIGNAL = 2;
 26     //定义一个DatabaseHelper对象
 27     private DatabaseHelper dh;
 28     
 29     static{
 30         //UriMatcher.NO_MATCH表示不匹配任何路径的返回码
 31         uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 32         uriMatcher.addURI(FirstProviderMetaData.AUTHORTY, "users", INCOMING_USER_COLLECTION);
 33         //后面加了#表示为单个:users下面的某一个users
 34         uriMatcher.addURI(FirstProviderMetaData.AUTHORTY, "users/#", INCOMING_USER_SIGNAL);
 35    }
 36     //新建一个HashMap,后面执行插入操作时有用
 37     public static HashMap<String, String> userProjectionMap;
 38     static
 39     {
 40         userProjectionMap = new HashMap<String, String>();
 41         //给数据库表中的列取别名
 42         userProjectionMap.put(UserTableMetaData._ID, UserTableMetaData._ID);
 43         userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);
 44     }
 45     
 46     //得到ContentProvider的数据类型,返回的参数URL所代表的数据类型
 47     @Override
 48     public String getType(Uri uri) {
 49         // TODO Auto-generated method stub
 50         System.out.println("getType");
 51         switch(uriMatcher.match(uri)){
 52         //matcher满足URL的前2项(即协议+路径)为第1种情况时,switch语句的值为URL的第3项,此处为INCOMING_USER_COLLECTION
 53         case INCOMING_USER_COLLECTION:
 54             return UserTableMetaData.CONTENT_TYPE;
 55         case INCOMING_USER_SIGNAL:
 56             return UserTableMetaData.CONTENT_TYPE_ITEM;
 57         default:
 58             throw new IllegalArgumentException("Unknown URI" + uri);
 59         }
 60     }
 61     //该函数的返回值是一个URL
 62     //这个URL表示的是刚刚使用这个函数的所插入的数据
 63     //content://zzl.FirstContentProvider/users/
 64     @Override
 65     public Uri insert(Uri uri, ContentValues values) {
 66         // TODO Auto-generated method stub
 67         System.out.println("insert");
 68         SQLiteDatabase db = dh.getWritableDatabase();
 69         long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
 70         if(rowId > 0){            
 71             //发出通知给监听器,说明数据已经改变
 72             //ContentUris为工具类
 73             Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
 74             getContext().getContentResolver().notifyChange(insertedUserUri, null);
 75             
 76             return insertedUserUri;
 77         }
 78         throw new SQLException("Failed to insert row into" + uri);
 79     }
 80 
 81     //回调函数,在ContentProvider创建的时候调用
 82     @Override
 83     public boolean onCreate() {
 84         // TODO Auto-generated method stub
 85         System.out.println("onCreate");
 86         dh = new DatabaseHelper(getContext(), FirstProviderMetaData.DATABASE_NAME);
 87         return true;
 88     }
 89     @Override
 90     public int delete(Uri uri, String selection, String[] selectionArgs) {
 91         // TODO Auto-generated method stub
 92         System.out.println("delete");
 93         return 0;
 94     }
 95 
 96     @Override
 97     public int update(Uri uri, ContentValues values, String selection,
 98             String[] selectionArgs) {
 99         // TODO Auto-generated method stub
100         System.out.println("update");
101         return 0;
102     }
103 
104     @Override
105     public Cursor query(Uri uri, String[] projection, String selection,
106             String[] selectionArgs, String sortOrder) {
107         // TODO Auto-generated method stub
108         System.out.println("query");
109         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
110         switch(uriMatcher.match(uri)){
111         case INCOMING_USER_COLLECTION:
112             qb.setTables(UserTableMetaData.TABLE_NAME);//设置表的名称
113             qb.setProjectionMap(userProjectionMap);//其中userProjectionMap为上面建立好了的Hashmap
114             break;
115         case INCOMING_USER_SIGNAL:
116             qb.setTables(UserTableMetaData.TABLE_NAME);//设置表的名称
117             qb.setProjectionMap(userProjectionMap);//其中userProjectionMap为上面建立好了的hashmap
118             //uri.getPathSegments()得到Path部分,即把URL的协议+authory部分去掉,把剩下的部分分段获取,这里取第
119             //一部分
120             qb.appendWhere(UserTableMetaData._ID + "=" +uri.getPathSegments().get(1));//设置where条件
121             break;
122         }
123         //排序
124         String orderBy;
125         if(TextUtils.isEmpty(sortOrder)){
126             orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;//传入的排序参数为空的时候采用默认的排序
127         }
128         else{
129             orderBy = sortOrder;//不为空时用指定的排序方法进行排序
130         }
131         SQLiteDatabase db = dh.getWritableDatabase();
132         //采用传入的参数进行查询
133         Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
134         //发出通知
135         c.setNotificationUri(getContext().getContentResolver(), uri);
136         return c;
137     }
138 }

总结:

    (1、 要在Manifest中加入

      <provider
               android:name="zzl.contentprovider.FirstContentProvider"
              android:authorities="zzl.contentprovider.FirstContentProvider"
     />

 

   

 

posted @ 2013-03-02 12:02  daomul  阅读(3211)  评论(0编辑  收藏  举报