1、Content Provider基本概念java
一、Content Provider提供爲存儲和獲取數據提供了統一的接口android
二、使用Content Provider能夠再不一樣的應用程序間共享數據sql
三、Android爲常見的一些數據提供了ContentPrivater(包括音頻、視頻、圖片和通信錄等等)數據庫
ContentProider使用表的形式來組織數據app
URItcp
一、每個ContentProvider都擁有一個公共的URI,這個URI用於表示這個ContentProvider所提供的數據。ide
二、Android所提供的ContentProvider存存放在android.provider函數
ContentProvider 所提供的函數ui
一、query() 查詢this
二、insert() 插入
三、update() 更新
四、delete() 刪除
五、getType() 獲得數據類型
六、onCreate() 建立時回調函數
實現ContentProvider的過程
一、定義一個CONTENT_URI常量
二、定義一個類,繼承ContentProvider
三、實現query,insert,update,delete,getType,onCreate方法
四、在AndroidManifest.xml當中進行聲明
package com.zyf.testcp; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class CPActivity extends Activity { Button insertButton; Button queryButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mian); insertButton = (Button) findViewById(R.id.insetButton); queryButton = (Button) findViewById(R.id.queryButton); insertButton.setOnClickListener(new InsertListener()); queryButton.setOnClickListener(new QueryListener()); } class InsertListener implements OnClickListener{ @Override public void onClick(View v) { ContentValues values = new ContentValues(); values.put(FirstProviderMetaData.UserTableMetaData.USER_NAME, "張三"); Uri uri = getContentResolver().insert( FirstProviderMetaData.UserTableMetaData.CONTENT_URI, values); System.out.println("uri--->"+uri.toString()); } } class QueryListener implements OnClickListener{ @Override public void onClick(View v) { Cursor c = getContentResolver().query( FirstProviderMetaData.UserTableMetaData.CONTENT_URI, null, null, null, null); while(c.moveToNext()){ System.out.println(c); int id = c.getInt(c.getColumnIndex(FirstProviderMetaData.UserTableMetaData._ID)); String name = c.getString(c.getColumnIndex(FirstProviderMetaData.UserTableMetaData.USER_NAME)); System.out.println("ID==>"+id+";NAME->"+name); } } } }
package com.zyf.testcp; import android.net.Uri; import android.provider.BaseColumns; public class FirstProviderMetaData { public static final String AUTHORIY = "com.zyf.testcp.FirstContentProvider"; //數據庫名稱 public static final String DATABASE_NAME = "FirstProvider.db"; //數據庫的版本 public static final int DATABASE_VERSION = 1; //表名 public static final String USERS_TABLE_NAME = "users"; public static final class UserTableMetaData implements BaseColumns{ //表名 public static final String TABLE_NAME = "users"; //訪問該ContentProvider的Uri public static final Uri CONTENT_URI = Uri.parse("content://"+AUTHORIY+"/users"); //該ContentProvider所返回的數據類型的定義 public static final String CONTENT_TYPE ="vnd.android.cursor.dir/vnd.firstprovider.user"; public static final String CONTENT_TYPE_ITEM ="vnd.android.cursor.item/vnd.firstprovider.user"; //列名 public static final String USER_NAME = "name"; //默認排序方法 public static final String DEFAULT_SORT_ORDER = "_id desc"; } }
package com.zyf.testcp; import java.util.HashMap; import com.zyf.db.DatabaseHelper; import com.zyf.testcp.FirstProviderMetaData.UserTableMetaData; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils; public class FirstContentProvider extends ContentProvider{ public static final UriMatcher uriMatcher; public static final int INCOMING_USER_COLLECTION = 1; public static final int INCOMING_USER_SINGLE = 2; private DatabaseHelper dh; static{ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "users", INCOMING_USER_COLLECTION); uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "users/#", INCOMING_USER_SINGLE); } public static HashMap<String, String> userProjectionMap; static{ userProjectionMap = new HashMap<String, String>(); userProjectionMap.put(UserTableMetaData._ID, UserTableMetaData._ID); userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME); } @Override public int delete(Uri arg0, String arg1, String[] arg2) { System.out.println("delete"); return 0; } /** * 根據傳入的Uri,返回該Uri所表示的數據類型 */ @Override public String getType(Uri uri) { // TODO Auto-generated method stub System.out.println("getType"); switch(uriMatcher.match(uri)){ case INCOMING_USER_COLLECTION: return UserTableMetaData.CONTENT_TYPE; case INCOMING_USER_SINGLE: return UserTableMetaData.CONTENT_TYPE_ITEM; default: throw new IllegalArgumentException("Unknow URI"+uri); } } /** * 該函數的返回值是一個Uri,這個Uri表示的是剛剛使用這個函數所插入的數據 * content://com.zyf.cp.FirstContentProvider/users/1 */ @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub System.out.println("insert"); SQLiteDatabase db = dh.getWritableDatabase(); long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values); if(rowId>0){ Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId); //通知監聽器,數據已經改變 getContext().getContentResolver().notifyChange(insertedUserUri, null); System.out.println(insertedUserUri); return insertedUserUri; } throw new SQLException("Failed to insert row into"+uri); } @Override public boolean onCreate() { dh = new DatabaseHelper(getContext(), FirstProviderMetaData.DATABASE_NAME); System.out.println("onCreate"); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); switch (uriMatcher.match(uri)) { case INCOMING_USER_COLLECTION: qb.setTables(UserTableMetaData.TABLE_NAME); qb.setProjectionMap(userProjectionMap); break; case INCOMING_USER_SINGLE: qb.setTables(UserTableMetaData.TABLE_NAME); qb.setProjectionMap(userProjectionMap); qb.appendWhere(UserTableMetaData._ID + "=" + uri.getPathSegments().get(1)); break; } String orderBy; if(TextUtils.isEmpty(sortOrder)){ orderBy = UserTableMetaData.DEFAULT_SORT_ORDER; }else{ orderBy = sortOrder; } SQLiteDatabase db = dh.getWritableDatabase(); Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy); c.setNotificationUri(getContext().getContentResolver(),uri); System.out.println("query"); return c; } @Override public int update(Uri arg0, ContentValues values, String whereClause, String[] whereArgs) { // TODO Auto-generated method stub System.out.println("insert"); SQLiteDatabase db = dh.getWritableDatabase(); long rowId = db.update(UserTableMetaData.TABLE_NAME, values, whereClause, whereArgs); Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(insertedUserUri, null); return 0; } }
package com.zyf.db; import com.zyf.testcp.FirstProviderMetaData; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; //DatabaseHelper做爲一個訪問SQLite的助手類,提供兩個方面的功能 //第一,getReadableDatabase(),getWriteableDatabase()能夠得到SQLiteDatabase對象,經過對象能夠對數據庫進行 //第二,提供了onCreate()和onUpdate()兩個回調函數,容許咱們在建立和升級數據庫的時候,進行本身的操做 public class DatabaseHelper extends SQLiteOpenHelper{ private static final int VERSION = 1; public DatabaseHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } public DatabaseHelper(Context context, String name){ this(context, name, VERSION); } public DatabaseHelper(Context context, String name, int version) { this(context, name, null,version); } //該函數在第一次建立數據庫的時候執行,其實是在第一次獲得SQLiteDatabase對象的時候,纔會調用這個方法 @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub System.out.println("create a Database"); db.execSQL("create table " + FirstProviderMetaData.USERS_TABLE_NAME+ "("+FirstProviderMetaData.UserTableMetaData._ID+" " + "INTEGER PRIMARY KEY AUTOINCREMENT," + FirstProviderMetaData.UserTableMetaData.USER_NAME+" varchar(20));"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub System.out.println("update a Database"); } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.zyf.testcp" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".CPActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <provider android:name="com.zyf.testcp.FirstContentProvider" android:authorities="com.zyf.testcp.FirstContentProvider"></provider> </application> </manifest>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <Button android:id="@+id/insetButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="插入數據" /> <Button android:id="@+id/queryButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="查詢數據" /> </LinearLayout>