ContentProvider的使用方法

来源:互联网 发布:python 元组列表排序 编辑:程序博客网 时间:2024/06/05 09:09

这回事使用ContentProvider来跨进程通信,一般都是结合数据库来使用,所以通信的数据一般都是固定结构,数据量也比较大。
我会创建两个工程ContentServer和ContentClient
先上代码
ContentServer

package com.android.student.database;public class StudentDbHelper extends SQLiteOpenHelper{    private Context context;    public StudentDbHelper(Context context,String name,int version)    {        super(context,name,null,version);        this.context=context;    }    @Override    public void onCreate(SQLiteDatabase db)    {        String createSQL="create table "+StudentWords.TABLE_NAME+"("+StudentWords.ID                +" integer primary key autoincrement,"                +StudentWords.NAME+" varchar,"                +StudentWords.SCORE+" integer,"                +StudentWords.ADDR+" varchar)";        db.execSQL(createSQL);    }    @Override    public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)    {        //升级版本时,可能要执行表结构的修改之类,此处暂时不考虑升级问题,因而只是用Toast提示        Toast.makeText(context,                "newVersion:"+newVersion+" will replace oldVersion:"+oldVersion,                Toast.LENGTH_LONG).show();    }}
package com.android.student.provider;public class StudentProvider extends ContentProvider{    private static final String TAG="StudentProvider";    private static UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);    private static final int STUDENT_WITH_ID=1;    private static final int STUDENT=2;    private StudentDbHelper dbHelper;    static    {        matcher.addURI(StudentWords.AUTHORITY,"student/#",STUDENT_WITH_ID);        //matcher.addURI(StudentWords.AUTHORITY, "student", SINGLE_STUDENT);        //注意其中的#为通配符        matcher.addURI(StudentWords.AUTHORITY, "student", STUDENT);    }    @Override    public boolean onCreate()    {        dbHelper=new StudentDbHelper(this.getContext(),"student.db3",1);        return true;    }    @Override    public String getType(Uri uri)    {        switch(matcher.match(uri))        {            case STUDENT_WITH_ID:                return "vnd.android.cursor.item/com.android.student";            case STUDENT:                return "vnd.android.cursor.dir/com.android.student";            default:                throw new IllegalArgumentException("Unknown Uri:"+uri);        }    }    /**     * 由单一的selection这一个筛选条件组合成包含id的复杂筛选条件     * @param uri     * @param selection     * @return     */    private String getComplexSelection(Uri uri,String selection)    {        long id=ContentUris.parseId(uri);        String complexSelection=StudentWords.ID+"="+id;        if(selection!=null&&!"".equals(selection))        {            complexSelection+=" and "+selection;        }        return complexSelection;    }    @Override    public int delete(Uri uri,String selection,String[]selectionArgs) {        SQLiteDatabase db=dbHelper.getReadableDatabase();        int num=0;        switch(matcher.match(uri))        {            case STUDENT_WITH_ID:                String complexSelection=getComplexSelection(uri,selection);                num=db.delete(StudentWords.TABLE_NAME, complexSelection, selectionArgs);                break;            case STUDENT:                num=db.delete(StudentWords.TABLE_NAME,selection,selectionArgs);                break;            default:                throw new IllegalArgumentException("Unknown Uri:"+uri);        }        //通知数据已经改变        getContext().getContentResolver().notifyChange(uri, null);        return num;    }    @Override    public Uri insert(Uri uri, ContentValues values) {        SQLiteDatabase db=dbHelper.getReadableDatabase();        switch(matcher.match(uri))        {            case STUDENT_WITH_ID:            case STUDENT:                long rowId=db.insert(StudentWords.TABLE_NAME, StudentWords.ID,values);                if(rowId>0)                {                    Uri studentUri=ContentUris.withAppendedId(uri, rowId);                    //如果设置了观察者的话,要通知所有观察者                    getContext().getContentResolver().notifyChange(studentUri, null);                    return studentUri;                }                break;            default:                throw new IllegalArgumentException("Unknow Uri:"+uri);        }        return null;    }    /**     * 注意其中的projection其实是columns,即列名数组     */    @Override    public Cursor query(Uri uri, String[] projection, String selection,                        String[] selectionArgs, String sortOrder) {        SQLiteDatabase db=dbHelper.getReadableDatabase();        switch(matcher.match(uri))        {            //这其实是包含id信息的情况            case STUDENT_WITH_ID:                String complexSelection=getComplexSelection(uri,selection);                return db.query(StudentWords.TABLE_NAME,projection,complexSelection,selectionArgs,null,null,sortOrder);            //这是不带数字的情况,但是也未必就是好多个,一个也可以。            case STUDENT:                return db.query(StudentWords.TABLE_NAME                        ,projection,selection,selectionArgs,null,null,sortOrder);            default:                throw new IllegalArgumentException("Unknow Uri"+uri);        }    }    @Override    public int update(Uri uri, ContentValues values, String selection,                      String[] selectionArgs)    {        SQLiteDatabase db=dbHelper.getWritableDatabase();        int num=0;        switch(matcher.match(uri))        {            case STUDENT_WITH_ID:                String complexSelection=getComplexSelection(uri,selection);                num=db.update(StudentWords.TABLE_NAME, values, complexSelection, selectionArgs);                break;            case STUDENT:                num=db.update(StudentWords.TABLE_NAME, values, selection,selectionArgs);                break;            default:                throw new IllegalArgumentException("Unknow Uri:"+uri);        }        getContext().getContentResolver().notifyChange(uri,null);        return num;    }}
package com.android.student.utils;/** * Created by Administrator on 2017/4/1. */import android.net.Uri;/** * 这里定义了与ContentProvider相关的字符串以及Student对应的数据表中的字段 * @author Bettar * */public class StudentWords {    //注意Manifest文件中的authorities属性要跟这里保持一致。    public static final String AUTHORITY="com.android.student.provider";    public static final Uri STUDENT_WITH_ID_URI=Uri.parse("content://"+AUTHORITY+"/student");    public static final Uri STUDENT_URI=Uri.parse("content://"+AUTHORITY+"/student");    public static final String TABLE_NAME="student";    public static final String ID="id";    public static final String NAME="name";    public static final String SCORE="score";    public static final String ADDR="address";}
<provider    android:name="com.android.student.provider.StudentProvider"    android:authorities="com.android.student.provider"    android:exported="true"></provider>

ContentClient

package com.android.student.studentcontentresolver;public class MainActivity extends Activity implements View.OnClickListener{    ContentResolver contentResolver;    private EditText nameET,scoreET,addressET;    private Button insertButton;    private EditText inputNameET;    private Button searchButton;    private EditText inputIdForUpdateET,inputIdForDeleteET;    private Button updateButton,deleteButton;    private void initView()    {        nameET=(EditText)findViewById(R.id.nameET);        scoreET=(EditText)findViewById(R.id.scoreET);        addressET=(EditText)findViewById(R.id.addrET);        insertButton=(Button)findViewById(R.id.insertButton);        inputNameET=(EditText)findViewById(R.id.inputNameET);        searchButton=(Button)findViewById(R.id.searchButton);        inputIdForUpdateET=(EditText)findViewById(R.id.inputIdET);        inputIdForDeleteET=(EditText)findViewById(R.id.inputIdForDeleteET);        updateButton=(Button)findViewById(R.id.updateButton);        deleteButton=(Button)findViewById(R.id.deleteButton);        insertButton.setOnClickListener(this);        searchButton.setOnClickListener(this);        updateButton.setOnClickListener(this);        deleteButton.setOnClickListener(this);    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        contentResolver=getContentResolver();        initView();    }    @Override    public void onClick(View view)    {        switch(view.getId())        {            case R.id.insertButton:                insert();                break;            case R.id.searchButton:                query();                break;            case R.id.updateButton:                update();                break;            case R.id.deleteButton:                delete();                break;            default:                break;        }    }    private void insert()    {        String name=nameET.getText().toString();        String score=scoreET.getText().toString();        String addr=addressET.getText().toString();        ContentValues values=new ContentValues();        values.put(StudentWords.NAME, name);        values.put(StudentWords.SCORE, new Integer(score));        values.put(StudentWords.ADDR, addr);        //contentResolver.insert(StudentWords.SINGLE_STUDENT_URI, values);        //一个是多个的特例,所以此处用MANY_STUDENTS_URI即可。        contentResolver.insert(StudentWords.STUDENT_URI, values);        Toast.makeText(getBaseContext(), "添加学生信息成功", Toast.LENGTH_SHORT).show();    }    private void query()    {        String name=inputNameET.getText().toString();        //Cursor cursor=contentResolver.query(uri, projection, selection, selectionArgs, sortOrder)        Cursor cursor=contentResolver.query(StudentWords.STUDENT_URI, null, "name like ? or address like ?", new String[]{"%"+name+"%","%"+name+"%"}, null);        Toast.makeText(getBaseContext(), getResult(cursor), Toast.LENGTH_LONG).show();    }    private void update()    {        //Uri updateUri=StudentWords.SINGLE_STUDENT_URI        //更新id值为id的记录        Integer id=new Integer(inputIdForUpdateET.getText().toString());        Uri updateUri=ContentUris.withAppendedId(StudentWords.STUDENT_WITH_ID_URI,id);        ContentValues values=new ContentValues();        values.put(StudentWords.NAME,"VictorWang");        contentResolver.update(updateUri, values, null, null);    }    private void delete()    {        //删除id值为id的记录        Integer id=new Integer(inputIdForDeleteET.getText().toString());        Uri deleteUri=ContentUris.withAppendedId(StudentWords.STUDENT_WITH_ID_URI, id);        contentResolver.delete(deleteUri, null, null);    }    private List<String>convertCursor2List(Cursor cursor)    {        List<String>result=new ArrayList<String>();        while(cursor.moveToNext())        {            result.add(cursor.getString(1)+"  ");            result.add(cursor.getString(2)+"  ");            result.add(cursor.getString(3)+"  ");        }        return result;    }    private String getResult(Cursor cursor)    {        StringBuilder sb=new StringBuilder();        while(cursor.moveToNext())        {            sb.append(cursor.getString(1)+"  ");            sb.append(cursor.getString(2)+"  ");            sb.append(cursor.getString(3)+"\n");        }        return sb.toString();    }}

这个代码和上一个工程一样,用作存储数据

package com.android.student.utils;/** * Created by Administrator on 2017/4/1. */import android.net.Uri;/** * 这里定义了与ContentProvider相关的字符串以及Student对应的数据表中的字段 * @author Bettar * */public class StudentWords {    //注意Manifest文件中的authorities属性要跟这里保持一致。    public static final String AUTHORITY="com.android.student.provider";    public static final Uri STUDENT_WITH_ID_URI=Uri.parse("content://"+AUTHORITY+"/student");    public static final Uri STUDENT_URI=Uri.parse("content://"+AUTHORITY+"/student");    public static final String TABLE_NAME="student";    public static final String ID="id";    public static final String NAME="name";    public static final String SCORE="score";    public static final String ADDR="address";}
<?xml version="1.0" encoding="utf-8"?><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"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.android.student.studentcontentresolver.MainActivity">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="以下为输入参数:" />    <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/nameET"/>    <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/scoreET"/>    <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/addrET"/>    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="insert"        android:gravity="center_horizontal"        android:id="@+id/insertButton"        android:onClick="onClick"/>    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="以下为查询参数:" />    <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/inputNameET"/>    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="search"        android:gravity="center_horizontal"        android:id="@+id/searchButton"        android:onClick="onClick"/>    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="以下为Update参数:" />    <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/inputIdET"/>    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Update"        android:gravity="center_horizontal"        android:id="@+id/updateButton"/>    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="以下为删除参数:" />    <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/inputIdForDeleteET"/>    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="delete"        android:gravity="center_horizontal"        android:id="@+id/deleteButton"/></LinearLayout>

首先ContentServer的注册文件里的android:exported=”true”必须要有,这个没有其他应用无法调用这个Provider,这个我觉得很奇怪,因为首先这个属性默认是true,而且它是基于Binder的,我使用Binder和AIDL的时候不需要这个设置这个属性,如果有人知道原因清发评论让我涨知识。

android:authorities=”com.android.student.provider”
这个值是作为调用Provider的凭证,可以说是一种密码
而且设置URI也是基于这个值来建立的
public static final Uri STUDENT_WITH_ID_URI=Uri.parse(“content://”+AUTHORITY+”/student”);
public static final Uri STUDENT_URI=Uri.parse(“content://”+AUTHORITY+”/student”);

大家也察觉了其实调用ContentProvider非常容易,只要一行代码就行了,连接也是,因为它是高度集成的Binder,因为他的URI设置很倾向于数据库,所以我们建立数据库来配合这个使用,才显得代码很多。
再见

0 0
原创粉丝点击