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