自定义contentprovider

contentprovider是不同应用程序之间交换数据

自定义contentprovider的步骤:

(1)定义一个contract类,描述数据库中的相关元数据,定义所要用到的常量。

package com.bobo.myprovider;

import android.net.Uri;
import android.provider.BaseColumns;

public class PersonDataBase {
    public  static final String AUTHORITY="com.bobo.myprovider";
    public static final String DataBaseName="MyDataBase";
    public static final int Version=1;
    public static final Uri CONTENT_URI=Uri.parse("content://"+AUTHORITY);
    
    public static class PersonTable implements BaseColumns{
    //表名
    public static final String TableName="PersonTable";
    //表中的姓名列
    public static final String NAME="name";
    //表中的年龄列
    public static final String AGE="age";
    //整体查询的返回类型
    public static final String CONTENT_TYPE="vnd.android.cursor.dir/person";
    //单条查询的返回类型
    public static final String CONTENT_ITEM_TYPE="vnd.android.cursor.item/person";
    //默认的排序方式
    public static final String DEFAULT_SORT_ORDER = PersonTable.NAME + " ASC";
    //访问路径
    public static final String CONTENT_DIRECTORY="PersonTable";
    //这个表对应的contentUri
    public static final Uri CONTENT_URI=Uri.withAppendedPath(PersonDataBase.CONTENT_URI,PersonDataBase.PersonTable.TableName);
    
    }
}

(2)如何使用数据库进行数据存储,定义一个sqlhelper类

(除了数据库之外,还可以采用其他任何的结构化数据存储方式)。如果需要存储诸如图片,音频等二进制文件,可以采用文件结合数据库的形式,此时在下面的contentprovider需要覆写一个getStreamTypes的方法。)

/**
 * 
 */
package com.bobo.myprovider;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * @author bobo
 *
 */
public class MyDataHelper extends SQLiteOpenHelper {

    public MyDataHelper(Context context, String name, CursorFactory factory,
            int version) {
        super(context, name, factory, version);
    }

    /* (non-Javadoc)
     * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sqlString="CREATE TABLE "+PersonDataBase.PersonTable.TableName+"("
                +PersonDataBase.PersonTable._ID+" INTEGER PRIMARY KEY,"
                +PersonDataBase.PersonTable.NAME+" VARCHAR(50) NOT NULL,"
                +PersonDataBase.PersonTable.AGE+" INTEGER NOT NULL)";
        db.execSQL(sqlString);
    }

    /* (non-Javadoc)
     * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String sql="DROP TABLE IF EXISTS"+PersonDataBase.PersonTable.TableName;
        db.execSQL(sql);
        this.onCreate(db);
    }

}

(3)定义一个类继承contentProvider,覆写其中的各个方法。其中会借助一些辅助类,诸如UriMatcher,contentUris等(下面的示例仅仅完成了插入功能)

package com.bobo.myprovider;

import android.annotation.SuppressLint;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class MyProvider extends ContentProvider {
    private static UriMatcher matcher;
    private static final int GET_LIST = 1;
    private static final int GET_ITEM = 2;
    private MyDataHelper helper;
    static {
        matcher = new UriMatcher(UriMatcher.NO_MATCH);
        matcher.addURI(PersonDataBase.AUTHORITY,
                PersonDataBase.PersonTable.CONTENT_DIRECTORY, GET_LIST);
        matcher.addURI(PersonDataBase.AUTHORITY,
                PersonDataBase.PersonTable.TableName + "/#", GET_ITEM);
    }

    @Override
    public boolean onCreate() {
        this.helper = new MyDataHelper(this.getContext(),
                PersonDataBase.DataBaseName, null, PersonDataBase.Version);
        return true;
    }

    @SuppressLint("NewApi")
    @Override
    public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
        // 当返回文件类型的数据时,需要覆写这个方法
        return super.getStreamTypes(uri, mimeTypeFilter);
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        Cursor result;
        System.out.println("***"+matcher.match(uri));
        SQLiteDatabase db = this.helper.getReadableDatabase();
        switch (matcher.match(uri)) {
        case GET_LIST:
            return db.query(PersonDataBase.PersonTable.TableName, projection, selection, selectionArgs, null, null, sortOrder);
        case GET_ITEM:
            selectionArgs=new String[]{ContentUris.parseId(uri)+""};
            return db.query(PersonDataBase.PersonTable.TableName, projection, "_id=?", selectionArgs, null, null, sortOrder);
        default:
            throw new IllegalArgumentException("IllegalArgumentException");

        }
    }
    
    @Override
    public String getType(Uri uri) {
        switch (matcher.match(uri)) {
        case GET_LIST:
            return PersonDataBase.PersonTable.CONTENT_TYPE;
        case GET_ITEM:
            return PersonDataBase.PersonTable.CONTENT_ITEM_TYPE;
        default:
            throw new IllegalArgumentException("IllegalArgumentException");
        }
    }

    // 返回插入的记录对应的uri
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        System.out.println("***"+matcher.match(uri));
        Cursor result;
        SQLiteDatabase db = this.helper.getWritableDatabase();
        long id;
        switch (matcher.match(uri)) {
        case GET_LIST:
            id = db.insert(PersonDataBase.PersonTable.TableName, null, values);
            return ContentUris.withAppendedId(uri, id);
        case GET_ITEM:
            id = db.insert(PersonDataBase.PersonTable.TableName, null, values);
            String uriPath = uri.toString();
            String path = uriPath.subSequence(0, uriPath.lastIndexOf("/"))
                    .toString() + id;
            return Uri.parse(path);
        default:
            throw new IllegalArgumentException("IllegalArgumentException");
        }
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        
        return 0;
    }

}

(4)在配置文件中进行contentprovider的配置,还可以配置权限,以及不需要权限通过intent访问contentPovider等功能。(详见api文档)

 <provider
            android:name=".MyProvider"
            android:authorities="com.bobo.myprovider" >
        </provider>

 

(5)具体的使用借助于contentResolver

 

package com.bobo.myprovider;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {
    private Button insert;
    private Button query;
    private Button delete;
    private Button update;
    private ContentResolver resolver;
    private ListView lv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        resolver = this.getContentResolver();
        insert = (Button) this.findViewById(R.id.insert);
        query = (Button) this.findViewById(R.id.query);
        delete = (Button) this.findViewById(R.id.delete);
        update = (Button) this.findViewById(R.id.update);
        lv = (ListView) this.findViewById(R.id.lv);
        insert.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                ContentValues values = new ContentValues();
                values.put("name", "test");
                values.put("age", 28);
                Uri uri = resolver.insert(
                        PersonDataBase.PersonTable.CONTENT_URI, values);

                Toast.makeText(getApplicationContext(), uri.toString(),
                        Toast.LENGTH_SHORT).show();
            }
        });
        query.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // String[] projection=new String{"name","age"};
                // 首先查询全部
                Cursor cursor = resolver.query(
                        PersonDataBase.PersonTable.CONTENT_URI, null, null,
                        null, PersonDataBase.PersonTable.DEFAULT_SORT_ORDER);
                //操作cursor结构集合
                MainActivity.this.startManagingCursor(cursor);
                System.out.println(cursor.getColumnName(0)+";"+cursor.getColumnName(1)+cursor.getColumnName(2));
                for(cursor.moveToFirst();cursor.isAfterLast();cursor.moveToNext()){
                    System.out.println(cursor.getString(cursor.getColumnIndex("name"))+";"+cursor.getInt(cursor.getColumnIndex("age"))+";Id="+cursor.getInt(0));
                }
                /*    SimpleCursorAdapter adapter = new SimpleCursorAdapter(
                        getApplicationContext(),
                        android.R.layout.simple_list_item_2, cursor,
                        new String[] {"_id", "name"}, new int[] {
                                android.R.id.text1, android.R.id.text2 });
                lv.setAdapter(adapter);*/
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}

 

posted @ 2013-06-16 13:41  bobo的学习笔记  阅读(460)  评论(0编辑  收藏  举报