ContentProvider简单示例

这里写个简单的例子用来存储用户信息。PeopleInfo为用户信息类

package com.wwd.mycontentprovider;

import android.net.Uri;

/**
 * Created by wwd on 2016/8/9.
 */
public class PeopleInfo {

    //contentprovider的域名
    public static final String AUTHORITY = "com.wwd.mycontentprovider.peopleinfo";
    public static final String PATH_SINGLE = "people/#";
    public static final String PATH_MULTIPLE = "people";
    //多项MIME
    public static final String MIME_DIR_MULTIPLE = "vnd.android.cursor.dir";
    //单项MIME
    public static final String MIME_ITEM_SINGLE = "vnd.android.cursor.item";
    public static final String TABLE_NAME = "peopleinfo";

    //contentprovider的URI
    public static final String CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_MULTIPLE;
    public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING);

    //contentprovider单项的URI
    public static final String ALONE_CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_SINGLE;
    public static final Uri CONTENT_URI_ALONE = Uri.parse(ALONE_CONTENT_URI_STRING);


    public static class People{
        public static final String ID = "_id";
        public static final String NAME = "name";
        public static final String AGE = "age";
    }
}

Contentprovider的uri格式如下:
[content://] [com.wwd.mycontentprovider.peopleinfo] [/people] [/#]
|—–A——||————————B—————————–||—-C—-||-D-|
B是AUTHORITY。
C是PATH_MULTIPLE也就是数据类型,如果表中不止保持人物信息,还有其他类型的数据比如货物数据时就需要C来区分了。
D是单项ID,就是每一项item的_id。

我们知道contentprovider的数据列表都是保存在SQL内的,所以先要简单的写一个SQL。具体如下

package com.wwd.mycontentprovider;

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

/**
 * Created by wwd on 2016/8/9.
 */
public class PeopleInfoSQLite extends SQLiteOpenHelper {

    private static final  String DB_CREATE = "create table "+
            PeopleInfo.TABLE_NAME + "("+PeopleInfo.People.ID + " integer primary key autoincrement, "+
            PeopleInfo.People.NAME + " text not null, " + PeopleInfo.People.AGE + " integer);";

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

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DB_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

然后就是主要的contentprovider部分

package com.wwd.mycontentprovider;

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;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;

/**
 * Created by wwd on 2016/8/9.
 */
public class PeopleProvider extends ContentProvider {

    public static final int MULTIPLE_PEOPLE = 1;
    public static final int SINGLE_PEOPLE = 2;
    public static final UriMatcher uriMatcher;

    private static final int SQL_VERSION = 1;
    private static final String DB_NAME = "people_db";

    private PeopleInfoSQLite peopleSqlite;

    //绑定匹配值,uriMatcher.match(uri))返回SINGLE_PEOPLE为单项,MULTIPLE_PEOPLE为多项
    static{
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(PeopleInfo.AUTHORITY, PeopleInfo.PATH_SINGLE, SINGLE_PEOPLE );
        uriMatcher.addURI(PeopleInfo.AUTHORITY, PeopleInfo.PATH_MULTIPLE , MULTIPLE_PEOPLE );
    }

    @Override
    public boolean onCreate() {
        peopleSqlite = new PeopleInfoSQLite(getContext(), DB_NAME, null, SQL_VERSION);
        SQLiteDatabase database = peopleSqlite.getWritableDatabase();
        if(database == null)
            return false;
        else
            return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteDatabase database = peopleSqlite.getReadableDatabase();
        switch(uriMatcher.match(uri)){
            case SINGLE_PEOPLE:
                long id = ContentUris.parseId(uri);
                String where = PeopleInfo.People.ID + "=" + id;
                if(selection != null && !"".equals(selection)){
                    selection = where + "and" + selection;
                }
                return database.query(PeopleInfo.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
            case MULTIPLE_PEOPLE:
                return database.query(PeopleInfo.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
        }
        return null;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)){
            case MULTIPLE_PEOPLE:
                return PeopleInfo.MIME_DIR_MULTIPLE;
            case SINGLE_PEOPLE:
                return PeopleInfo.MIME_ITEM_SINGLE;
        }
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase database = peopleSqlite.getWritableDatabase();
        long id = database.insert(PeopleInfo.TABLE_NAME, null, values);
        Uri newUri = ContentUris.withAppendedId(uri, id);
        getContext().getContentResolver().notifyChange(uri, null);
        return newUri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int number = 0;
        SQLiteDatabase database = peopleSqlite.getWritableDatabase();
        Log.i("wwdlog","delete selection = "+selection);
        switch (uriMatcher.match(uri)){
            case MULTIPLE_PEOPLE:
                number = database.delete(PeopleInfo.TABLE_NAME, selection, selectionArgs);
                break;

            //根据URI的ID来删除单项数据
            case SINGLE_PEOPLE:
                String segment = uri.getPathSegments().get(1);
                Log.i("wwdlog","segment = " + segment + ", selection = " + selection);
                number = database.delete(PeopleInfo.TABLE_NAME, PeopleInfo.People.ID + "=" + segment
                        + (!TextUtils.isEmpty(selection) ? " and (" + selection + ')' : ""), selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unsupported URI:" + uri);
        }
        getContext().getContentResolver().notifyChange(uri,null);
        return number;

    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        SQLiteDatabase database = peopleSqlite.getWritableDatabase();
        int number = 0;
        switch (uriMatcher.match(uri)){
            case MULTIPLE_PEOPLE:
                number = database.update(PeopleInfo.TABLE_NAME, values, selection, selectionArgs);
                break;
            case SINGLE_PEOPLE:
                String segment = uri.getPathSegments().get(1);
                number = database.update(PeopleInfo.TABLE_NAME, values, PeopleInfo.People.ID + "=" + segment, selectionArgs);
                break;
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return number;
    }
}

这里解释一下query的参数作用,其他相关函数也同理。
public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, String sortOrder)
第一个参数Uri就是PeopleInfo.CONTENT_URI。
第二个参数,projection,这个参数告诉Provider要返回的内容(列Column),如果我们只需要NAME,那么我们可以写成如下格式

Cursor cursor = contentResolver.query(PeopleInfo.CONTENT_URI,new String[]{PeopleInfo.People.NAME}, null, null, null); 

第三个参数,selection,设置条件,相当于SQL语句中的where。null表示不进行筛选。比如我们要查找john,可以

String name = john;
getContentResolver().query(PeopleInfo.CONTENT_URI_ALONE,  null,  PeopleInfo.People.NAME + "='"+name+"'", null, null);

第四个参数,selectionArgs,这个参数是要配合第三个参数使用的,如果你在第三个参数里面有?,那么你在selectionArgs写的数据就会替换掉?具体如下

getContentResolver().query(PeopleInfo.CONTENT_URI_ALONE,  null,  PeopleInfo.People.NAME + “=?”, new = String[]{name}, null);

第五个参数,sortOrder,按照什么进行排序,相当于SQL语句中的Order by。

这样基本的contentprovider基本写完最后附上activity的调用

package com.wwd.mycontentprovider;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button addButton;
    private Button delButton;
    private Button changeButton;
    private Button searchButton;
    private TextView showView;
    private EditText editName;
    private EditText editAge;
    private ContentResolver resolver;

    private PeopleChangeObserver mObserver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        resolver = this.getContentResolver();
        addButton = (Button)findViewById(R.id.bt1);
        delButton = (Button)findViewById(R.id.bt2);
        changeButton = (Button)findViewById(R.id.bt3);
        searchButton = (Button)findViewById(R.id.bt4);
        editName = (EditText)findViewById(R.id.ed1);
        editAge = (EditText)findViewById(R.id.ed2);
        showView = (TextView)findViewById(R.id.show_list);
        mObserver = new PeopleChangeObserver(null);

        initView();
    }
    class PeopleChangeObserver extends ContentObserver{
        public PeopleChangeObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            Log.i("wwdlog","PeopleChangeObserver!! ");
        }
    }

    @Override
    protected void onResume() {
        getContentResolver().registerContentObserver(PeopleInfo.CONTENT_URI, true, mObserver);
        super.onResume();
    }

    @Override
    protected void onPause() {
        getContentResolver().unregisterContentObserver(mObserver);
        super.onPause();
    }

    private void initView(){
        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ContentValues values = new ContentValues();
                values.put(PeopleInfo.People.NAME, editName.getText().toString());
                values.put(PeopleInfo.People.AGE, Integer.parseInt(editAge.getText().toString()));
                Uri newUri = resolver.insert(PeopleInfo.CONTENT_URI, values);
                Log.i("wwdlog","add success newUri = "+newUri);
            }
        });

        delButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = editName.getText().toString();
                String age = editAge.getText().toString();
                if (!name.equals("") || !age.equals("")) {
                    if(!name.equals(""))
                        getContentResolver().delete(PeopleInfo.CONTENT_URI, PeopleInfo.People.NAME + "='"+name+"'", null);
                    } else {
                        Toast.makeText(MainActivity.this, "请输入删除条件",
                            Toast.LENGTH_LONG).show();
                    }

            }
        });

        changeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = editName.getText().toString();
                String age = editAge.getText().toString();
                if(!name.equals("")&&!age.equals("")){
                    Cursor cursor = getContentResolver().query(PeopleInfo.CONTENT_URI, null, PeopleInfo.People.NAME + "='"+name+"'", null, null);
                    if(cursor != null){
                        ContentValues values = new ContentValues();
                        values.put(PeopleInfo.People.NAME, name);
                        values.put(PeopleInfo.People.AGE, Integer.parseInt(age));
                        getContentResolver().update(PeopleInfo.CONTENT_URI, values, PeopleInfo.People.NAME + "=?", new String[]{name});
                    }
                }else {
                    Toast.makeText(MainActivity.this, "请输入姓名年龄",
                            Toast.LENGTH_LONG).show();
                }
            }
        });

        searchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                refreshList();
            }
        });

        refreshList();
    }

    private void refreshList(){
        Cursor cursor = getContentResolver().query(PeopleInfo.CONTENT_URI, null, null, null, null);
        String table_list = null;
        if(cursor != null && cursor.moveToFirst()){
            do{
                int age = cursor.getInt(cursor.getColumnIndex(PeopleInfo.People.AGE));
                String name = cursor.getString(cursor.getColumnIndex(PeopleInfo.People.NAME));
                Log.i("wwdlog","init age = "+age+", name = "+name);
                table_list += name + " " + age + '\n';
            }while(cursor.moveToNext());
        }
        Log.i("wwdlog", "table_list = "+table_list);
        showView.setText(table_list);
    }
}

layout如下


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <Button
            android:id="@+id/bt1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="添加" />

        <Button
            android:id="@+id/bt2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="删除" />

        <Button
            android:id="@+id/bt3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="更改年龄" />

        <Button
            android:id="@+id/bt4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="查询" />

        <EditText
            android:id="@+id/ed1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="输入name条件进行增删改查" />

        <EditText
            android:id="@+id/ed2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="输age条件进行增删改查" />
    LinearLayout>

    <TextView
        android:id="@+id/show_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">TextView>

LinearLayout>

AndroidManifest.xml别忘了加上定义

<provider
     android:authorities="com.wwd.mycontentprovider.peopleinfo"
     android:name=".PeopleProvider" />
application>

你可能感兴趣的:(android基础)