ContentProvider實現的是數據庫操做的封裝,而且能夠實現數據之間的共享。也就是說,利用ContentProvider實現的數據存儲能夠在外部應用程序中訪問的到。具體過程以下:
java
一:擴展ContentProvider類提供數據訪問接口
android
擴展SQLiteOpenHelper類,提供數據庫表的建立與更新(具體詳情請見上一篇博文)數據庫
注:這裏建議數據庫的表名,列名提取成全局靜態常量,以方便後面的調用。ide
這裏建立的數據庫爲:quan.db。數據庫表名爲:user。列名有兩項,分別爲:_id(主鍵)和title。即
工具
public class MySqlite extends SQLiteOpenHelper { //數據庫表名,列名提取成全局靜態常量 public static final String TABLE_NAME = "user"; public static final String TABLE_TITLE = "title"; public static final String TABLE_ID = "_id"; //構造方法 public MySqlite(Context context) { super(context, "quan.db", null, 1); } //數據庫表的建立 @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table " + TABLE_NAME + "(" + TABLE_ID + " integer primary key autoincrement," + TABLE_TITLE + " text not null)"); } //數據庫表的更新 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } |
二:擴展ContentProvider抽象類,實現其中的六個抽象方法,完成對數據庫操做的封裝
spa
1:URI簡介
xml
URI統一資源標識符,說白了,就是惟一標識資源的一個字串。一樣的在ContentProvider中也須要惟一的一個字符串,標識提供數據的惟一性。也正是根據URI在Manifest.xml文件中的註冊,外部應用程序纔可能查找獲得ContentProvider所提供的數據。對象
具體的註冊方式:
blog
<provider android:name="繼承自ContentProvider類的類名" android:authorities="包名.繼承自ContentProvider類的類名" > </provider> |
具體的URI格式:繼承
public static final Uri URI = Uri.parse("content://包名.繼承自Contentprovider的類名稱(也就是註冊中android:authorities的屬性值)"); |
注意:字符串中「content://」爲固定格式。
2:六個抽象方法及做用
(1)onCreate():主要用來初始化使用到的工具,在ContentProvider對象建立以後就會被調用。好比繼承自SQLiteOpenHelper類的對象的初始化,SQLiteDatabase中得到可讀可寫權限對象的初始化等。
(2)query():返回類型爲Cursor,經過對數據庫具備可讀權限對象的query方法,完成外部應用數據庫關於表的查詢操做。即:提供外部應用的從ContentProvider中獲取數據。
(3)insert():返回類型爲Uri,經過對數據庫具備可寫權限對象的insert方法,完成數據庫關於表的插入操做。即外部應用向ContentProvider中插入數據。
(4)delete():返回類型爲int,經過對數據庫具備可寫權限對象的delete方法,完成數據庫中關於表的刪除操做。即外部應用從ContentProvider中刪除數據。
(5)update():返回類型爲int,經過對數據庫具備可寫權限對象的update方法,完成數據庫中關於表的更新操做。即外部應用更新ContentProvider中的數據。
(6)getType():用來標識ContentProvider中數據的類型。
3:具體實現
public class MyCP extends ContentProvider { // 統一資源標識符 public static final Uri URI = Uri .parse("content://com.example.day08_mycontentprovider.MyCP"); // 聲明數據庫的建立與更新對象 private MySqlite mySqlite; // 得到數據可讀可寫的對象 private SQLiteDatabase dbWriter, dbReader; // 得到表名,列名等靜態常量 private static final String CP_TABLE_NAME = MySqlite.TABLE_NAME; private static final String CP_TABLE_TITLE = MySqlite.TABLE_TITLE; private static final String CP_TABLE_ID = MySqlite.TABLE_ID; @Override public boolean onCreate() { mySqlite = new MySqlite(getContext());// 數據庫表的建立 dbWriter = mySqlite.getWritableDatabase();// 實例化可讀可寫對象 dbReader = mySqlite.getReadableDatabase(); return true; } // 數據庫關於表的查詢 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return dbReader.query(CP_TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); } // 數據庫關於表的查插入 @Override public Uri insert(Uri uri, ContentValues values) { dbWriter.insert(CP_TABLE_NAME, null, values); return uri; } // 數據庫關於表的刪除 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return dbWriter.delete(CP_TABLE_NAME, selection, selectionArgs); } // 數據庫關於表的更新 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return dbWriter.update(CP_TABLE_NAME, values, selection, selectionArgs); } // 返回數據類型 @Override public String getType(Uri uri) { return null; } } |
三:內部應用程序的引用
在應用程序中,經過getContentResolver()方法調用ContentProvider中的幾個方法,完成數據中表的操做
public class MainActivity extends Activity { // 獲得惟一標識ContentProvider的URI public Uri uri = MyCP.URI; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); addDB(); // updateDB(); // deleteDB(); selectDB(); } // 添加,經過getContentResolver()得到到ContentProvider的數據解析對象 public void addDB() { ContentValues cv = new ContentValues(); cv.put("title", "HelloWord"); getContentResolver().insert(uri, cv);// 調用ContentProvider的insert方法,實現數據的添加 } // 查詢 public void selectDB() { // 調用ContentProvider的query方法,實現數據的查詢 Cursor cursor = getContentResolver().query(uri, null, null, null, null); while (cursor.moveToNext()) { System.out .println(cursor.getString(cursor.getColumnIndex("title"))); } } // 修改 public void updateDB() { // 調用ContentProvider的update方法,實現數據的修改 ContentValues cv = new ContentValues(); cv.put("title", "我更名了,我叫張三"); getContentResolver().update(uri, cv, null, null); } // 刪除 public void deleteDB() { // 調用ContentProvider的delete方法,實現數據的刪除 getContentResolver().delete(uri, null, null); } } |
四:外部應用程序的引用
1:提取ContentProvider的惟一標識符URI爲靜態常量,其值爲同上。
2:經過getContentResolver()方法調用ContentProvider中的幾個方法,完成數據中表的操做。
public class MainActivity extends Activity { //提取統一資源標識符URI,才能找獲得ContentProvider所存儲的數據 public static final Uri URI = Uri.parse("content://com.example.day08_mycontentprovider.MyCP"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); selectDB();//對方法的調用 } //經過getContentResolver()方法調用ContentProvider中的幾個方法,完成數據中表的操做。 public void selectDB(){ Cursor cursor = getContentResolver().query(URI, null, null, null, null); while(cursor.moveToNext()){ System.out.println(cursor.getString(cursor.getColumnIndex("title"))); } } } |
五:結果
內部應用:數據庫中的表存在於data/data/包名/database/***.db中,導出,運用SQLite Export查看存在於表中的數據
外部應用:在控制檯輸出數據庫中表的數據
08-31 10:31:39.158: I/System.out(285): HelloWord |