首先,ContentProvider(內容提供者)是android中的四大組件之一,可是在通常的開發中,可能使用的比較少。 ContentProvider爲不一樣的軟件之間數據共享,提供統一的接口。也就是說,若是咱們想讓其餘的應用使用咱們本身程序內的數據,就可使用ContentProvider定義一個對外開放的接口,從而使得其餘的應用可使用我們應用的文件、數據庫內存儲的信息。固然,本身開發的應用須要給其餘應用共享信息的需求可能比較少見,可是在Android系統中,不少系統自帶應用,好比聯繫人信息,圖片庫,音頻庫等應用,爲了對其餘應用暴露數據,因此就使用了ContentProvider機制。因此,咱們仍是要學習ContentProvider的基本使用,在遇到獲取聯繫人信息,圖片庫,音頻庫等需求的時候,才能更好的實現功能html
Android系統爲了讓咱們更好的對外暴露數據,提供了統一的接口,因此定義了抽象類ContentProvider,所以,若是咱們想對外提供數據,咱們須要繼承ContentProvider,而且實現下面的這幾個方法:
onCreate() 當咱們的provider初始化時被調用,咱們應該在這個方法裏面完成部分初始化操做 query() 查詢方法,用於給調用者返回數據 insert() 插入操做,用於讓外部應用插入數據到內容提供者中 update() 更新操做,用於更新內容提供者的數據 delete() 用於刪除數據 getType 返回內容提供者的MIME Type
上面這些方法,當咱們繼承自ContentProvider的時候,eclipse會自動的給咱們添加,可是這並不表明咱們每一個方法都須要自定義實現。若是咱們只但願給其餘應用提供數據,而不容許其餘應用修改咱們的數據,那麼咱們只須要實現onCreate(),getType()和query()這三個方法就能夠了,其餘的三個方法咱們能夠根據業務需求,實現或者是不實現。
由於通常使用ContentProvider向外部暴露數據庫的信息,所以,本篇將以使用ContentProvider向其餘應用暴露數據庫信息爲例,講解ContentProvider的基本使用。
Android中SQLite數據庫的建立和使用,本篇再也不介紹,不清楚的請看這篇文章 SQLite數據庫的簡單實用android
假設讀者已經學會了SQLite數據庫的使用,而且已經創建好了數據庫,下面咱們開始寫咱們的ContentProvider。 由於註釋解析的比較詳細,因此就不過多解釋了數據庫
1 /** 2 * 內容提供者 3 * 4 * @author ZhaoKaiQiang 5 * @time 2014年6月6日 6 */ 7 public class StudentProvider extends ContentProvider { 8 // 數據庫操做類,用於獲取SQLiteDatabase 9 private MyDbOpenHelper dbHelper; 10 11 private static final int STUDENT = 1; 12 private static final int STUDENTS = 2; 13 14 // UriMatcher類是一個很重要的類,由於咱們須要根據傳入的uri,來判斷執行相對應的操做 15 private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH); 16 17 // 靜態代碼塊用於初始化MATCHER須要匹配的uri 18 static { 19 // MATCHER.addURI(主機名(用於惟一標示一個ContentProvider,這個須要和清單文件中的authorities屬性相同),路徑(能夠用來表示咱們要操做的數據,路徑的構建應根據業務而定),返回值(用於匹配uri的時候,做爲匹配的返回值)); 20 MATCHER.addURI("com.example.mydbdemo.StudentProvider", "student", STUDENTS); 21 MATCHER.addURI("com.example.mydbdemo.StudentProvider", "student/#", STUDENT); 22 } 23 24 // 進行數據的初始化操做 25 @Override 26 public boolean onCreate() { 27 dbHelper = new MyDbOpenHelper(getContext()); 28 return false; 29 } 30 31 // 查詢 32 // 若是uri爲 content://com.example.mydbdemo.StudentProvider/student 33 // 則表明查詢全部的student表內的數據 34 // 若是uri爲 content://com.example.mydbdemo.StudentProvider/student/6 35 // 則表明查詢student表內id=6的數據 36 @Override 37 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 38 39 SQLiteDatabase db = dbHelper.getReadableDatabase(); 40 //判斷傳入的uri到底匹配哪個,從而實現不一樣的業務需求 41 switch (MATCHER.match(uri)) { 42 //查詢所有的學生信息 43 case STUDENTS: 44 //db.query(代表, 要查詢的列(是一個String數組), where條件, where條件中的參數, groupBy, having, sortOrder); 45 return db.query("student", projection, selection, selectionArgs, null, null, sortOrder); 46 //查詢某一個id對應的學生的信息 47 case STUDENT: 48 //取出咱們要查詢的數據的id 49 long id = ContentUris.parseId(uri); 50 String where = "id=" + id; 51 //將selection查詢信息拼接到咱們的where條件中 52 if (selection != null && !"".equals(selection)) { 53 where = selection + " and " + where; 54 } 55 return db.query("student", projection, where, selectionArgs, null, null, sortOrder); 56 //如uri不匹配,拋出不合法參數的異常 57 default: 58 throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); 59 } 60 61 } 62 63 // 插入 64 @Override 65 public Uri insert(Uri uri, ContentValues values) { 66 SQLiteDatabase db = dbHelper.getWritableDatabase(); 67 switch (MATCHER.match(uri)) { 68 case STUDENTS: 69 long id = db.insert("student", "name", values); 70 return ContentUris.withAppendedId(uri, id); 71 default: 72 throw new IllegalArgumentException("Uri不匹配"); 73 } 74 75 } 76 77 //刪除數據 78 @Override 79 public int delete(Uri uri, String selection, String[] selectionArgs) { 80 SQLiteDatabase db = dbHelper.getWritableDatabase(); 81 int count = 0; 82 switch (MATCHER.match(uri)) { 83 case STUDENTS: 84 count = db.delete("student", selection, selectionArgs); 85 return count; 86 87 case STUDENT: 88 long id = ContentUris.parseId(uri); 89 String where = "id=" + id; 90 if (selection != null && !"".equals(selection)) { 91 where = selection + " and " + where; 92 } 93 count = db.delete("student", where, selectionArgs); 94 return count; 95 96 default: 97 throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); 98 } 99 } 100 101 //更新數據 102 @Override 103 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 104 SQLiteDatabase db = dbHelper.getWritableDatabase(); 105 int count = 0; 106 switch (MATCHER.match(uri)) { 107 case STUDENTS: 108 count = db.update("student", values, selection, selectionArgs); 109 return count; 110 111 case STUDENT: 112 long id = ContentUris.parseId(uri); 113 String where = "id=" + id; 114 if (selection != null && !"".equals(selection)) { 115 where = selection + " and " + where; 116 } 117 count = db.update("student", values, where, selectionArgs); 118 return count; 119 120 default: 121 throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); 122 } 123 } 124 125 // 用於獲取MIME Type 126 @Override 127 public String getType(Uri uri) { 128 switch (MATCHER.match(uri)) { 129 case STUDENT: 130 return "vnd.android.cursor.item/student"; 131 case STUDENTS: 132 return "vnd.android.cursor.dir/student"; 133 default: 134 throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); 135 } 136 137 } 138 139 }
咱們在定義好咱們的ContentProvider以後,由於ContentProvider數據四大組件之一,所以咱們還須要在AndroidManifest清單文件中進行註冊才能使用,下面是註冊信息
數組
1 <!-- 不要忘記exported這個屬性,若是不加,可能會致使外部程序訪問失敗,錯誤信息爲權限拒絕 --> 2 <!-- authorities這個屬性就是咱們在ContentProvider中使用的addURI方法時的第一個參數的取值 --> 3 <provider 4 android:name="com.example.mydbdemo.StudentProvider" 5 android:exported="true" 6 android:authorities="com.example.mydbdemo.StudentProvider" > 7 </provider>
注意,provider的聲明和activity同樣,都是在application節點進行聲明的。
至此,咱們就完成了咱們本身的ContentProvider的生命,其餘的應用如今就可使用咱們往外部暴露的數據信息了。app
咱們已經定義好了咱們本身的ContentProvider,那麼外部應用如何調用呢? 下面,我將新建一個測試單元工程,完成對ContentProvider的各個方法的測試
添加方法測試eclipse
1 //使用ContentProvider添加數據的測試 2 public void testadd() throws Throwable { 3 //獲取ContentResolver對象,完成對ContentProvider的調用 4 ContentResolver contentResolver = this.getContext().getContentResolver(); 5 //構建咱們的uir,這個uri 6 Uri insertUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student"); 7 ContentValues values = new ContentValues(); 8 values.put("name", "zhaokaikai"); 9 values.put("age", 91); 10 values.put("school", "bbbb"); 11 //返回值爲咱們剛插入進入的數據的uri地址 12 Uri uri = contentResolver.insert(insertUri, values); 13 Log.i(TAG, uri.toString()); 14 }
刪除方法測試ide
1 //使用ContentProvider刪除數據的測試 2 public void testDelete() throws Throwable { 3 ContentResolver contentResolver = this.getContext().getContentResolver(); 4 //刪除id爲6的學生信息 5 Uri deleteUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student/6"); 6 contentResolver.delete(deleteUri, null, null); 7 }
修改方法測試單元測試
1 //使用ContentProvider更新數據的測試 2 public void testUpdate() throws Throwable { 3 ContentResolver contentResolver = this.getContext().getContentResolver(); 4 //更新id = 6 的學生信息 5 Uri updateUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student/6"); 6 ContentValues values = new ContentValues(); 7 values.put("name", "testUp"); 8 values.put("age", "101"); 9 values.put("school", "ccccc"); 10 contentResolver.update(updateUri, values, null, null); 11 }
查詢學習
1 //使用ContentProvider查詢數據的測試 2 public void testFind() throws Throwable { 3 ContentResolver contentResolver = this.getContext().getContentResolver(); 4 //這個uri用於查詢全部的數據,若查詢某個id的數據,則構建下面的uri 5 //Uri selectUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student/要查詢的id"); 6 Uri selectUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student"); 7 Cursor cursor = contentResolver.query(selectUri, null, null, null, "id desc"); 8 while (cursor.moveToNext()) { 9 int id = cursor.getInt(cursor.getColumnIndex("id")); 10 String name = cursor.getString(cursor.getColumnIndex("name")); 11 int age = cursor.getInt(cursor.getColumnIndex("age")); 12 String school = cursor.getString(cursor.getColumnIndex("school")); 13 Log.i(TAG, "id=" + id + ",name=" + name + ",age=" + age +",school="+school); 14 } 15 }
上面的方法都通過了單元測試。
好了,至此,咱們就使用ContentProvider實現了在第三方應用中對咱們應用的數據庫進行增刪改查等操做,若有疑問,請留言。測試
轉載自:http://www.it165.net/pro/html/201406/15166.html