Android ContentProvider完整案例


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();
        }
    }
}

運行結果為:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM