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