ContentData類,提供數據常量:
/** * 提供ContentProvider對外的各種常量,當外部數據需要訪問的時候,就可以參考這些常量操作數據。 * @author HB * */ public class ContentData { public static final String AUTHORITY = "hb.android.contentProvider"; public static final String DATABASE_NAME = "teacher.db"; //創建 數據庫的時候,都必須加上版本信息;並且必須大於4 public static final int DATABASE_VERSION = 4; public static final String USERS_TABLE_NAME = "teacher"; public static final class UserTableData implements BaseColumns { public static final String TABLE_NAME = "teacher"; //Uri,外部程序需要訪問就是通過這個Uri訪問的,這個Uri必須的唯一的。 public static final Uri CONTENT_URI = Uri.parse("content://"+ AUTHORITY + "/teacher"); // 數據集的MIME類型字符串則應該以vnd.android.cursor.dir/開頭 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/hb.android.teachers"; // 單一數據的MIME類型字符串應該以vnd.android.cursor.item/開頭 public static final String CONTENT_TYPE_ITME = "vnd.android.cursor.item/hb.android.teacher"; /* 自定義匹配碼 */ public static final int TEACHERS = 1; /* 自定義匹配碼 */ public static final int TEACHER = 2; public static final String TITLE = "title"; public static final String NAME = "name"; public static final String DATE_ADDED = "date_added"; public static final String SEX = "SEX"; public static final String DEFAULT_SORT_ORDER = "_id desc"; public static final UriMatcher uriMatcher; static { // 常量UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // 如果match()方法匹配content://hb.android.teacherProvider/teachern路徑,返回匹配碼為TEACHERS uriMatcher.addURI(ContentData.AUTHORITY, "teacher", TEACHERS); // 如果match()方法匹配content://hb.android.teacherProvider/teacher/230,路徑,返回匹配碼為TEACHER uriMatcher.addURI(ContentData.AUTHORITY, "teacher/#", TEACHER); } } }
SQLite操作類DBOpenHelper
/** * 這個類繼承SQLiteOpenHelper抽象類,用於創建數據庫和表。創建數據庫是調用它的父類構造方法創建。 * @author HB */ public class DBOpenHelper extends SQLiteOpenHelper { // 在SQLiteOepnHelper的子類當中,必須有該構造函數,用來創建一個數據庫; public DBOpenHelper(Context context, String name, CursorFactory factory, int version) { // 必須通過super調用父類當中的構造函數 super(context, name, factory, version); // TODO Auto-generated constructor stub } // public DBOpenHelper(Context context, String name) { // this(context, name, VERSION); // } public DBOpenHelper(Context context, String name, int version) { this(context, name, null, version); } /** * 只有當數據庫執行創建 的時候,才會執行這個方法。如果更改表名,也不會創建,只有當創建數據庫的時候,才會創建改表名之后 的數據表 */ @Override public void onCreate(SQLiteDatabase db) { System.out.println("create table"); db.execSQL("create table " + ContentData.UserTableData.TABLE_NAME + "(" + ContentData.UserTableData._ID + " INTEGER PRIMARY KEY autoincrement," + ContentData.UserTableData.NAME + " varchar(20)," + ContentData.UserTableData.TITLE + " varchar(20)," + ContentData.UserTableData.DATE_ADDED + " long," + ContentData.UserTableData.SEX + " boolean)" + ";"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
內容提供者類
/** * 這個類給外部程序提供訪問內部數據的一個接口 * @author HB * */ public class TeacherContentProvider extends ContentProvider { private DBOpenHelper dbOpenHelper = null; // UriMatcher類用來匹配Uri,使用match()方法匹配路徑時返回匹配碼 private static final UriMatcher uriMatcher=new UriMatcher(UriMatcher.NO_MATCH); /** * 是一個回調函數,在ContentProvider創建的時候,就會運行,第二個參數為指定數據庫名稱,如果不指定,就會找不到數據庫; * 如果數據庫存在的情況下是不會再創建一個數據庫的。(當然首次調用 在這里也不會生成數據庫必須調用SQLiteDatabase的 getWritableDatabase,getReadableDatabase兩個方法中的一個才會創建數據庫) */ @Override public boolean onCreate() { //這里會調用 DBOpenHelper的構造函數創建一個數據庫; dbOpenHelper = new DBOpenHelper(this.getContext(), ContentData.DATABASE_NAME, ContentData.DATABASE_VERSION); return true; } /** * 當執行這個方法的時候,如果沒有數據庫,他會創建,同時也會創建表,但是如果沒有表,下面在執行insert的時候就會出錯 * 這里的插入數據也完全可以用sql語句書寫,然后調用 db.execSQL(sql)執行。 */ @Override public Uri insert(Uri uri, ContentValues values){ //獲得一個可寫的數據庫引用,如果數據庫不存在,則根據onCreate的方法里創建; SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); long id = 0; switch (uriMatcher.match(uri)) { case TEACHERS: id = db.insert("teacher", null, values); // 返回的是記錄的行號,主鍵為int,實際上就是主鍵值 return ContentUris.withAppendedId(uri, id); case TEACHER: id = db.insert("teacher", null, values); String path = uri.toString(); return Uri.parse(path.substring(0, path.lastIndexOf("/"))+id); // 替換掉id default: throw new IllegalArgumentException("Unknown URI " + uri); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); int count = 0; switch (uriMatcher.match(uri)) { case TEACHERS: count = db.delete("teacher", selection, selectionArgs); break; case TEACHER: // 下面的方法用於從URI中解析出id,對這樣的路徑content://hb.android.teacherProvider/teacher/10 // 進行解析,返回值為10 long personid = ContentUris.parseId(uri); String where = "_ID=" + personid; // 刪除指定id的記錄 where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : ""; // 把其它條件附加上 count = db.delete("teacher", where, selectionArgs); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } db.close(); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); int count = 0; switch (uriMatcher.match(uri)) { case TEACHERS: count = db.update("teacher", values, selection, selectionArgs); break; case TEACHER: // 下面的方法用於從URI中解析出id,對這樣的路徑content://com.ljq.provider.personprovider/person/10 // 進行解析,返回值為10 long personid = ContentUris.parseId(uri); String where = "_ID=" + personid;// 獲取指定id的記錄 where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";// 把其它條件附加上 count = db.update("teacher", values, where, selectionArgs); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } db.close(); return count; } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case TEACHERS: return CONTENT_TYPE; case TEACHER: return CONTENT_TYPE_ITME; default: throw new IllegalArgumentException("Unknown URI " + uri); } } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); switch (uriMatcher.match(uri)) { case TEACHERS: return db.query("teacher", projection, selection, selectionArgs, null, null, sortOrder); case TEACHER: // 進行解析,返回值為10 long personid = ContentUris.parseId(uri); String where = "_ID=" + personid;// 獲取指定id的記錄 where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";// 把其它條件附加上 return db.query("teacher", projection, where, selectionArgs, null, null, sortOrder); default: throw new IllegalArgumentException("Unknown URI " + uri); } } }
文件清單:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="hb.android.contentProvider" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".TeacherActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <span style="white-space:pre"> </span><provider android:name=".TeacherContentProvider" <span style="white-space:pre"> </span>android:authorities="hb.android.contentProvider" /> </application> </manifest>
main.xml文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/insert" android:text="@string/insert" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Button android:id="@+id/query" android:text="@string/query" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Button android:id="@+id/querys" android:text="@string/querys" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Button android:id="@+id/update" android:text="@string/update" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Button android:id="@+id/delete" android:text="@string/delete" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </LinearLayout>
TeacherActivity內容提供者測試類
package hb.android.contentProvider; import java.util.Date; import android.app.Activity; import android.content.ContentResolver; 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; /** * 這個類用來測試ContentProvider是否可用。通過 給定的uri訪問,數據庫; * * @author HB * */ public class TeacherActivity extends Activity { Button insert; Button query; Button update; Button delete; Button querys; Uri uri = Uri.parse("content://hb.android.contentProvider/teacher"); /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); insert = (Button) findViewById(R.id.insert); query = (Button) findViewById(R.id.query); update = (Button) findViewById(R.id.update); delete = (Button) findViewById(R.id.delete); querys = (Button) findViewById(R.id.querys); // 綁定監聽器的兩種方法一; insert.setOnClickListener(new InsertListener()); query.setOnClickListener(new QueryListener()); // 方法二 update.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub ContentResolver cr = getContentResolver(); ContentValues cv = new ContentValues(); cv.put("name", "huangbiao"); cv.put("date_added", (new Date()).toString()); int uri2 = cr.update(uri, cv, "_ID=?", new String[]{"3"}); System.out.println("updated"+":"+uri2); } }); delete.setOnClickListener(new OnClickListener() { public void onClick(View v) { ContentResolver cr = getContentResolver(); cr.delete(uri, "_ID=?", new String[]{"2"}); } }); querys.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub ContentResolver cr = getContentResolver(); // 查找id為1的數據 Cursor c = cr.query(uri, null, null,null, null); System.out.println(c.getCount()); c.close(); } }); } class InsertListener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub ContentResolver cr = getContentResolver(); ContentValues cv = new ContentValues(); cv.put("title", "jiaoshou"); cv.put("name", "jiaoshi"); cv.put("sex", true); Uri uri2 = cr.insert(uri, cv); System.out.println(uri2.toString()); } } class QueryListener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub ContentResolver cr = getContentResolver(); // 查找id為1的數據 Cursor c = cr.query(uri, null, "_ID=?", new String[] { "1" }, null); //這里必須要調用 c.moveToFirst將游標移動到第一條數據,不然會出現index -1 requested , with a size of 1錯誤;cr.query返回的是一個結果集。 if (c.moveToFirst() == false) { // 為空的Cursor return; } int name = c.getColumnIndex("name"); System.out.println(c.getString(name)); c.close(); } } }
運行結果為:

