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

    运行结果为:

  • 相关阅读:
    VHDL中常用函数类型转换程序包
    Error (10309): VHDL Interface Declaration error in keyboard.vhd(63): interface object "scan_code" of mode out cannot be read. Change object mode to bu
    堆排序
    死锁及如何处理死锁-转载
    红黑书——算法导论
    Randomize select algorithm 随机选择算法
    转载:MATLAB画图常用调整代码
    广告营销学术语
    使用weka进行Cross-validation实验
    设计一个简单的,低耗的能够区分红酒和白酒的感知器(sensor)
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/5639670.html
Copyright © 2020-2023  润新知