Android自定义Content Provider

来源:互联网 发布:java api类库 编辑:程序博客网 时间:2024/06/03 06:49

这是Text_My_ContextProrityActivity.java

package com.pan.xiaod;


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.util.Log;

public class Text_My_ContextProrityActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ContentResolver cr = this.getContentResolver();
        ContentValues cv = new ContentValues() ; //cv用于存放ContentResolver的每一列项的值
        cv.put("name", "android基础教程设计") ;
        cr.insert(TestContentProviderMetaData.BookTableMetaData.CONTENT_URI,cv) ;
        cv.put("name", "java EE 编程技术"+"" );
        cr.insert(TestContentProviderMetaData.BookTableMetaData.CONTENT_URI,cv) ;
        Log.i("test" ,"begin load data") ;
        Cursor cursor = cr.query(TestContentProviderMetaData.BookTableMetaData.CONTENT_URI,null,null,null,null) ;
        //获取——ID字段索引
        int idIndex = cursor.getColumnIndex(TestContentProviderMetaData.BookTableMetaData._ID) ;
        //获得Name字段索引
        int nameIndex = cursor.getColumnIndex(TestContentProviderMetaData.BookTableMetaData.BOOK_NAME) ;
        String result = ""  ; //记录所有的信息 id+name+phone
        String tempid = null ;
        //遍历cursor提取数据
        for(cursor.moveToFirst();(!cursor.isAfterLast()) ; cursor.moveToNext()){
            result = result + cursor.getString(idIndex) ;
            result = result + cursor.getString(nameIndex) ;
            if(tempid == null) tempid = cursor.getString(idIndex ) ;//让tempid记录第一个id的值
        }
        Log.i("test" , result) ;
        Log.i("test" , "begin update data") ;
        Uri myURI = Uri.withAppendedPath(TestContentProviderMetaData.BookTableMetaData.CONTENT_SINGLE_URI, tempid) ;
        ContentValues values =  new ContentValues() ; //用于
        values.put("author", "panxiaomei") ;
        values.put("name", "Java EE 编程技术") ;
        cr.insert(myURI , values) ;
    }

}

******************************************************************************************************************

/*这是TextPrority.java (就是那个自定义的Content Provider)*/

package com.pan.xiaod;

import java.util.HashMap;
import com.pan.xiaod.TestContentProviderMetaData.BookTableMetaData;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;

public class TextPrority extends ContentProvider{
    public static final String TAG = "*TestPrority*" ;
    public DatabaseHelper openhelper = null ;
    //--创建列表名与JavaBean映射
    public static HashMap<String,String> sBookProjectionMap = null ;
    static {
        sBookProjectionMap = new HashMap<String,String>() ;
        //给新建的HashMap存放键值对,键:列名;值:类型
        sBookProjectionMap.put(BookTableMetaData._ID, BookTableMetaData._ID) ;
        sBookProjectionMap.put(BookTableMetaData.BOOK_NAME, BookTableMetaData.BOOK_NAME) ;
        sBookProjectionMap.put(BookTableMetaData.BOOK_ISBN,BookTableMetaData.BOOK_ISBN) ;
        sBookProjectionMap.put(BookTableMetaData.BOOK_AUTHOR,BookTableMetaData.BOOK_AUTHOR) ;
        sBookProjectionMap.put(BookTableMetaData.CREATED_DATE,BookTableMetaData.CREATED_DATE) ;
        sBookProjectionMap.put(BookTableMetaData.MODIFIED_DATE,BookTableMetaData.MODIFIED_DATE) ;
    }
    //--创建专用于content Provider的URI最佳适配器
    private static UriMatcher sUriMatcher = null ;
    //--注册URI请求类型
    private static final int INCOMMING_BOOK_COLLECTION_URI_INDICATOR = 1 ;
    private static final int INCOMMING_SINGLE_BOOK_URI_INDICATOR = 2 ;
    static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH) ;
        sUriMatcher.addURI(TestContentProviderMetaData.AUTHORITY, "books", INCOMMING_BOOK_COLLECTION_URI_INDICATOR) ;
        sUriMatcher.addURI(TestContentProviderMetaData.AUTHORITY, "books/#" ,INCOMMING_SINGLE_BOOK_URI_INDICATOR) ;
    }

    @Override
    /*
     * whereClause :控制删除的范围
     * 根据不同的uri进行不同的操作
     */
    public int delete(Uri uri, String whereClause, String[] whereArgs) {
        
        // TODO Auto-generated method stub
        Log.i(TAG,"del") ;
        SQLiteDatabase db = openhelper.getWritableDatabase() ; //获取SQL的写操作权
        int count = 0 ;
        switch(sUriMatcher.match(uri)){
        case INCOMMING_BOOK_COLLECTION_URI_INDICATOR:
            count = db.delete(BookTableMetaData.TABLE_NAME,whereClause,whereArgs) ;
            break ;
        case INCOMMING_SINGLE_BOOK_URI_INDICATOR:
            String rowID = uri.getPathSegments().get(1) ;//
            String where = BookTableMetaData._ID +"=" +rowID +(!TextUtils.isEmpty(whereClause)?"AND("+whereClause+')':"") ;//?什么意思,有什么用?
            count = db.delete(BookTableMetaData.TABLE_NAME,whereClause, whereArgs) ;
            break ;
        default :
            throw new IllegalArgumentException("Unknown URI" + uri) ;
        }
        this.getContext().getContentResolver().notifyChange(uri, null) ;
        return count;
    }

    @Override
    /*
     * 检索uri的读写权限、现在的输入输出状态
     * ?return这些String有什么用?
     */
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        switch(sUriMatcher.match(uri)){
            case INCOMMING_BOOK_COLLECTION_URI_INDICATOR :
                return BookTableMetaData.CONTENT_TYPE ;
            case INCOMMING_SINGLE_BOOK_URI_INDICATOR :
                return BookTableMetaData.CONTENT_ITEM_TYPE ;
            default :
                throw new IllegalArgumentException("Unknown URI"+uri) ;
        }
    }

    @Override
    /*
     * 功能:在指定的uri地址存放
     * values :存放着要插入表的内容
     */
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        Log.i(TAG ,"insert") ;
        long now = Long.valueOf(System.currentTimeMillis()) ; //当前系统时间
        if(values.containsKey(BookTableMetaData.CREATED_DATE) == false){
            values.put(BookTableMetaData.CREATED_DATE, now) ;
        }
        if(values.containsKey(BookTableMetaData.MODIFIED_DATE) == false){
            values.put(BookTableMetaData.MODIFIED_DATE, now) ;
        }
        if(values.containsKey(BookTableMetaData.BOOK_NAME) == false){
            //values.put(BookTableMetaData.BOOK.NAME,"null") ;
            throw new SQLException("Failed to insert now,because Book name is needed" + uri) ;
        }
        if(values.containsKey(BookTableMetaData.BOOK_ISBN) == false){
            values.put(BookTableMetaData.BOOK_ISBN, "Unknown ISBN") ;
        }
        if(values.containsKey(BookTableMetaData.BOOK_AUTHOR) == false){
            values.put(BookTableMetaData.BOOK_AUTHOR, "Unknown AUHTOR") ;
        }
        SQLiteDatabase db = openhelper.getWritableDatabase() ;//获取SQl的写权限,把values写进去,返回分配给新列的id给rowID
        long rowID = db.insert(BookTableMetaData.TABLE_NAME, BookTableMetaData.TABLE_NAME, values) ;
        if(rowID > 0 ){
            //把新id的列放到表的末尾,并把表的指针uri返回给insertbookUri
            Uri insertbookUri = ContentUris.withAppendedId(BookTableMetaData.CONTENT_URI, rowID) ;
            getContext().getContentResolver().notifyChange(insertbookUri, null) ;
            return insertbookUri ;
        }
        return null;
    }

    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        Log.i(TAG,"onCreat") ;
        openhelper = new DatabaseHelper(this.getContext()) ;
        Log.i(TAG , openhelper.toString()) ;
        return true;
    }

    @Override
    /*
     * projection : 可以返回的列
     * sortOrder:排序方式
     */
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        SQLiteQueryBuilder qb = null ;
        qb = new SQLiteQueryBuilder()  ;//帮助建立要求查询的sql数据
        switch(sUriMatcher.match(uri)){
            case INCOMMING_BOOK_COLLECTION_URI_INDICATOR :
                qb.setTables(BookTableMetaData.TABLE_NAME) ;//设置查询的表名
                qb.setProjectionMap(sBookProjectionMap) ;//根据上边的HashMap<String,String>来设置查询面图
                break ;
            case INCOMMING_SINGLE_BOOK_URI_INDICATOR :
                qb.setTables(BookTableMetaData.TABLE_NAME) ;
                qb.setProjectionMap(sBookProjectionMap) ;
                qb.appendWhere(BookTableMetaData._ID+"="+uri.getPathSegments().get(1)) ;//功能就是让数据只显示某一行,但怎么从语句中体现出来
                break ;
            default:
                    throw new IllegalArgumentException("Unknown URI"+uri) ;        
        }
        String orderBy = "" ;
        //判断sortOrder是否为空,null时把预置值付给orderBy
        if(TextUtils.isEmpty(sortOrder)){
            orderBy = BookTableMetaData.DEFAULT_SORT_ORDER ;    
        }
        else{
            orderBy = sortOrder ;
        }
        SQLiteDatabase db = openhelper.getReadableDatabase() ;//得到sql的读权限
        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy) ;//通过qb代理向sql进行查询
        int i  = c.getCount(); //统计行数
        ContentResolver cr = this.getContext().getContentResolver() ; //这个类提供了应用程序访问内容模型。
        c.setNotificationUri(cr, uri); //在查询时,随时观察数据是否有变动,
        return c;
    }

    @Override
    /*
     *
     */
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        Log.i(TAG, "update") ;
        SQLiteDatabase db = openhelper.getWritableDatabase() ;
        int count = 0 ;
        switch(sUriMatcher.match(uri)){
        case INCOMMING_BOOK_COLLECTION_URI_INDICATOR :
            count = db.update(BookTableMetaData.TABLE_NAME, values, selection, selectionArgs) ;
            break ;
        case INCOMMING_SINGLE_BOOK_URI_INDICATOR :
            String rowID = uri.getPathSegments().get(1) ;
            String where = "BookTableMetaData._ID"+"="+rowID+(!TextUtils.isEmpty(selection)?"AND("+selection+')':"") ;
            count = db.update(BookTableMetaData.TABLE_NAME, values, where, selectionArgs) ;
            break ;
        default :
            throw new IllegalArgumentException("Unknown URI"+uri) ;
        }
        getContext().getContentResolver().notifyChange(uri, null) ;
        return count;
    }
    public class DatabaseHelper extends SQLiteOpenHelper{

        public DatabaseHelper(Context context) {
        super(context,TestContentProviderMetaData.DATABASE_NAME , null ,TestContentProviderMetaData.DATABASE_VERSION);
            // TODO Auto-generated constructor stub
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub
            String sql = "CREATE TABLE"+ BookTableMetaData.TABLE_NAME
                        +"("+TestContentProviderMetaData.BookTableMetaData._ID
                        +BookTableMetaData.BOOK_NAME + "TEXT,"
                        +BookTableMetaData.BOOK_ISBN + "TEXT,"
                        +BookTableMetaData.BOOK_AUTHOR + "TEXT,"
                        +BookTableMetaData.CREATED_DATE + "INTEGER,"
                        +BookTableMetaData.MODIFIED_DATE + "INTEGER"
                        +");" ;
            Log.i(TAG, db.getPath()) ;
            db.execSQL(sql);//这个的功能是什么?
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // TODO Auto-generated method stub
            Log.i(TAG, "Update data from"+oldVersion+"to" + newVersion+ ",where will destroy old data!" ) ;
            String sql = "DROP TABLE IF EXISTE" + BookTableMetaData.TABLE_NAME ;
            db.execSQL(sql) ;
            onCreate(db) ;
        }
        
    }

}

class TestContentProviderMetaData{
    public static final String DATABASE_NAME = "book.db" ;
    public static final int DATABASE_VERSION = 1 ;
    public static final String AUTHORITY = "com.pan.xiaod.bookprovider" ;
    public static final String BOOK_TABLE_NAME = "books" ;
    // 用于存放不变值的class
    public static final class BookTableMetaData implements BaseColumns{
        public static final String TABLE_NAME = "books"  ;
        public static final String BOOK_NAME = "name" ;
        public static final String BOOK_ISBN = "isbn" ;
        public static final String BOOK_AUTHOR = "author" ;
        public static final String CREATED_DATE = "created" ;
        public static final String MODIFIED_DATE = "modified" ;
        public static final Uri CONTENT_URI = Uri.parse("content://"+AUTHORITY +"/books") ;
        public static final Uri CONTENT_SINGLE_URI  = Uri.parse("content://"+ AUTHORITY+"/books/#" ) ;
        //多记录
        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.androidbook.book" ;
        //单记录
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.androidbook.book" ;
        public static final String DEFAULT_SORT_ORDER = "modified DESC" ;    
    }
    
}

在运行后就出错,

LogCat的显示如下:

03-16 08:01:30.342: E/Database(404): Failure 1 (near "TABLEbooks": syntax error) on 0x22d5b8 when preparing 'CREATE TABLEbooks(_idnameTEXT,isbnTEXT,authorTEXT,createdINTEGER,modifiedINTEGER);'.
03-16 08:01:30.362: D/AndroidRuntime(404): Shutting down VM
03-16 08:01:30.362: W/dalvikvm(404): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
03-16 08:01:30.392: E/AndroidRuntime(404): FATAL EXCEPTION: main
03-16 08:01:30.392: E/AndroidRuntime(404): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pan.xiaod/com.pan.xiaod.Text_My_ContextProrityActivity}: android.database.sqlite.SQLiteException: near "TABLEbooks": syntax error: CREATE TABLEbooks(_idnameTEXT,isbnTEXT,authorTEXT,createdINTEGER,modifiedINTEGER);

03-16 08:01:30.392: E/AndroidRuntime(404):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.os.Looper.loop(Looper.java:123)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.app.ActivityThread.main(ActivityThread.java:4627)
03-16 08:01:30.392: E/AndroidRuntime(404):     at java.lang.reflect.Method.invokeNative(Native Method)
03-16 08:01:30.392: E/AndroidRuntime(404):     at java.lang.reflect.Method.invoke(Method.java:521)
03-16 08:01:30.392: E/AndroidRuntime(404):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-16 08:01:30.392: E/AndroidRuntime(404):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-16 08:01:30.392: E/AndroidRuntime(404):     at dalvik.system.NativeStart.main(Native Method)
03-16 08:01:30.392: E/AndroidRuntime(404): Caused by: android.database.sqlite.SQLiteException: near "TABLEbooks": syntax error: CREATE TABLEbooks(_idnameTEXT,isbnTEXT,authorTEXT,createdINTEGER,modifiedINTEGER);
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1727)
03-16 08:01:30.392: E/AndroidRuntime(404):     at com.pan.xiaod.TextPrority$DatabaseHelper.onCreate(TextPrority.java:219)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:106)
03-16 08:01:30.392: E/AndroidRuntime(404):     at com.pan.xiaod.TextPrority.insert(TextPrority.java:116)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.content.ContentProvider$Transport.insert(ContentProvider.java:174)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.content.ContentResolver.insert(ContentResolver.java:587)
03-16 08:01:30.392: E/AndroidRuntime(404):     at com.pan.xiaod.Text_My_ContextProrityActivity.onCreate(Text_My_ContextProrityActivity.java:20)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-16 08:01:30.392: E/AndroidRuntime(404):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-16 08:01:30.392: E/AndroidRuntime(404):     ... 11 more

请问这是什么错误吗? 求指教!