600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Android ContentProvider 内容提供者

Android ContentProvider 内容提供者

时间:2019-07-05 09:54:20

相关推荐

Android ContentProvider 内容提供者

ContentProvider 内容提供者,是Android四大组件之一。

一、简述

可以理解为一个特殊的存储数据的类型,它提供了一套标准的接口来获取和操作数据。可以把数据封装到ContentProvider 中,从而是这些数据可以被其他的应用程序所共享。搭建起了所有应用程序之间数据交换的桥梁!

1. 内容提供者可以将应用中的数据对外进行共享

2.内容提供者将数据的访问方式统一,不必针对不同数据类型采取不同的访问策略

3.内容提供者将数据封装,只暴露出我们希望提供给其他程序的数据

4.内容提供者中数据更改可被监听

二、创建内容提供者

定义类继承ContentProvider,根据需要重写内部方法

在清单文件的<application>节点下进行配置,<provider>标签中需要指定name和authorities属性

name为类名,包名从程序Package开始,以“.”开始

authorities:是访问Provider时的路径,要唯一

URI代表要操作的数据,由scheme、authorites、path三部分组成

content://com.bruce.contentprovider.demo/student

scheme:固定为content,代表访问内容提供者

authorites:<provider>节点中的authorites属性

path:程序定义的路径,可根据业务逻辑定义

--------------------------------------------------------------------------------------------------

<provider

android:name="com.bruce.contentprovider.demo.MyContentProvider"

android:authorities="com.bruce.contentprovider.demo"

></provider>

--------------------------------------------------------------------------------------------------

getType方法中:

如果返回数据是单条数据:vnd.android.cursor.item

如果返回数据是多条数据:vnd.android.cursor.dir

三、完成CRUD方法

当程序调用CRUD方法时会传入Uri,我们通过Uri判断调用者要操作的数据,可以使用工具类UriMatcher来判断Uri,addURI方法可以添加Uri,match方法可以匹配一个Uri判断其类型;根据业务逻辑操作数据。

1.onCreate() :初始化该ContentProvider

2.query(Uri,String[],String,Sring[],String) :通过Uri进行查询,返回Uri

3.intert(Uri,ContentValues):将数据插入到Uri所指定的位置

4.update(Uri,ContentValues,String,String []):更新uri指定位置的数据

5.delete(Uri,String,String[]):删除uri指定位置的数据

6.getType(Uri):返回数据的类型

四、建立contentprovider工程,添加单元测试(/kingshow123/p/sqlitecreate.html中有介绍)

注意:创建的内容提供者MyContentProvider,必须放在应用包(com.bruce.contentprovider),或者放在应用包的子包(com.bruce.contentprovider.demo)下。因为它是应用组件之一

五、创建DbOpenHelper类

package com.bruce.contentprovider.db;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class DbOpenHelper extends SQLiteOpenHelper {private static String name = "mycont.db";private static int version = 1;public DbOpenHelper(Context context) {super(context, name, null, version);}@Overridepublic void onCreate(SQLiteDatabase db) {String sql = "create table student( id integer primary key autoincrement,name varchar(64),address varchar(64))";db.execSQL(sql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {// TODO Auto-generated method stub}}

View Code

六、创建MyContentProvider类

package com.bruce.contentprovider.demo;import com.bruce.contentprovider.db.DbOpenHelper;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 .Uri;public class MyContentProvider extends ContentProvider {private DbOpenHelper helper;private final static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);private final static int STUDENT = 0;private final static int STUDENTS = 1;static{matcher.addURI("com.bruce.contentprovider.demo", "student/#", STUDENT); //单条记录matcher.addURI("com.bruce.contentprovider.demo", "student", STUDENTS); //多条记录 }@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {int count = -1;SQLiteDatabase database = helper.getWritableDatabase();switch (matcher.match(uri)) {case STUDENT:long id = ContentUris.parseId(uri);selection = (selection == null ? " id = " + id : " id = " + id + " and " + selection);count = database.delete("student", selection, selectionArgs);break;case STUDENTS:count = database.delete("student", selection, selectionArgs);break;default:throw new IllegalArgumentException("No match uri:" + uri);}return count;}@Overridepublic String getType(Uri uri) {switch (matcher.match(uri)) {case STUDENT:return "vnd.android.cursor.item/student";case STUDENTS:return "vnd.android.cursor.dir/student";default:throw new IllegalArgumentException("No match uri:" + uri);}}@Overridepublic Uri insert(Uri uri, ContentValues values) {Uri resultUri = null;switch (matcher.match(uri)) {case STUDENTS:SQLiteDatabase database = helper.getWritableDatabase();long id = database.insert("student", null,values);resultUri = ContentUris.withAppendedId(uri, id);break;default:throw new IllegalArgumentException("No match uri:" + uri);}return resultUri;}@Overridepublic boolean onCreate() {helper = new DbOpenHelper(getContext());return false;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {Cursor cursor = null;switch (matcher.match(uri)) {case STUDENT:long id = ContentUris.parseId(uri);selection = selection == null ? " id = " + id : " id = " + id + " and " + selection;case STUDENTS:SQLiteDatabase database = helper.getWritableDatabase();cursor = database.query("student", projection, selection, selectionArgs, null, null, sortOrder);break;default:throw new IllegalArgumentException("No match uri:" + uri);}return cursor;}@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {switch (matcher.match(uri)) {case STUDENT:long id = ContentUris.parseId(uri);selection = (selection == null ? " id = " + id : " id = " + id + " and " + selection);case STUDENTS:SQLiteDatabase database = helper.getWritableDatabase();return database.update("student", values, selection, selectionArgs); //directly return the number of rows affecteddefault:throw new IllegalArgumentException("No match uri:" + uri);}}}

View Code

七、创建MyTestProvider类

package com.bruce.contentprovider.test;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import .Uri;import android.test.AndroidTestCase;import android.util.Log;public class MyTestProvider extends AndroidTestCase {private String TAG = "MyTestProvider";public void insertStudent(){ContentResolver resolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student");ContentValues values = new ContentValues();values.put("name", "姚明");values.put("address", "上海");Uri reUri = resolver.insert(uri, values);Cursor cursor = resolver.query(reUri, null, null, null, null);if(cursor.moveToNext()){int id = cursor.getInt(0);String name = cursor.getString(1);String address = cursor.getString(2);Log.i(TAG, "-->test insert id:" + id + ",name:" + name + ",address:" + address);}}public void deleteStudent(){ContentResolver resolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student/5");//String selection = " name = ? ";//String[] selectionArgs = {"姚明"};//int count = resolver.delete(uri, selection, selectionArgs);int count = resolver.delete(uri, null, null);Log.i(TAG, "-->test delete count=" + count);}public void updateStudent(){ContentResolver resolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student/1");ContentValues values = new ContentValues();values.put("name", "邹市明");values.put("address","遵义");//String selection = " name = ? ";//String[] selectionArgs = {"老毛"};//int count = resolver.update(uri, values, selection, selectionArgs);int count = resolver.update(uri, values, null, null);Log.i(TAG, "-->test update count = " + count);}public void queryById(){ContentResolver resolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student/1");Cursor cursor = resolver.query(uri, null, null, null, null);while(cursor.moveToNext()){int id = cursor.getInt(0);String name = cursor.getString(1);String address = cursor.getString(2);Log.i(TAG, "--> test queryById id = " + id + ",name = " + name + ",address= " + address);}}public void queryByName(){Map<String, String> map = new HashMap<String, String>();ContentResolver resolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student");String selection = " name = ? ";String[] selectionArgs = {"姚明"};Cursor cursor = resolver.query(uri, null, selection, selectionArgs, null);int count = cursor.getColumnCount();while(cursor.moveToNext()){for(int i=0; i<count; i++){String cols_name = cursor.getColumnName(i);String cols_value = cursor.getString(cursor.getColumnIndex(cols_name));map.put(cols_name, cols_value);}}Log.i(TAG, "-->test queryByName:" + map.toString());}public void queryListStudent(){List<Map<String, String>> list = new ArrayList<Map<String,String>>();ContentResolver resolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student");Cursor cursor = resolver.query(uri, null, null, null, null);int count = cursor.getColumnCount();while(cursor.moveToNext()){Map<String, String> map = new HashMap<String, String>();for(int i=0; i<count; i++){String cols_name = cursor.getColumnName(i);String cols_value = cursor.getString(cursor.getColumnIndex(cols_name));map.put(cols_name, cols_value);}list.add(map);}Log.i(TAG, "-->test queryListStudent:" + list.toString());}public void testGetType(){ContentResolver resolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student/1");Log.i(TAG, "-->testGetType plus id:" + resolver.getType(uri));uri = Uri.parse("content://com.bruce.contentprovider.demo/student");Log.i(TAG, "-->testGetType:" + resolver.getType(uri));}}

View Code

八、监听内容提供者数据变化

在内容提供者中可以通知其他程序数据发生变化,通过Context的getContentResolver()方法获取ContentResolver,调用其notifyChange()方法发送数据修改通知;

在其他程序中可以通过ContentObserver监听数据变化

通过Context的getContentResolver()方法获取ContentResolver

调用其registerContentObserver()方法指定对某个Uri注册ContentObserver

自定义ContentObserver,重写onChange()方法获取数据

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.需要被监听的对象(例如)下面放入代码

首先需要调用一下 getContext.getcontentResolver().notifyChange(uri,null);放在删除添加 或者其他的方法后面

2.然后在Activity中继承ContentObserver类 自己实现oncreate方法在方法中写具体的业务代码 比如是

Private classMyContentObserver extends contentObserver(){

Public MyContentObserver(Handle handle){

Super(handle)

}

Public void onChange(){// 具体的业务代码

//可以用toast类去实现一些显示的功能

}

}

3.在主类中注册uri

GetcontentResolver().registerContentObserver(“需要注册的uri”,ture,new MyContentObserver(new handle() )) 方法

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

发送修改通知:

public Uri insert(Uri uri, ContentValues values) {Uri resultUri = null;switch (matcher.match(uri)) {case STUDENTS:SQLiteDatabase database = helper.getWritableDatabase();long id = database.insert("student", null,values);// Notify registered observers that a row was updated. 注册 observer // @param observer The observer that originated the change, may be null // 产生改变的Observer. 此处为Provider带来的改变,传 nullthis.getContext().getContentResolver().notifyChange(uri, null);// 发送修改通知//resultUri = Uri.parse("content://com.bruce.contentprovider.demo/student" + id);resultUri = ContentUris.withAppendedId(uri, id);break;default:throw new IllegalArgumentException("No match uri:" + uri);}return resultUri;}

View Code

也可以在其他应用中定义一个ContentObserver,监听Uri所对应的内容提供者的变化

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//定义一个ContentObserverContentObserver observer = new ContentObserver(new Handler()) {/** * Returns true if this observer is interested in notifications for* changes made through the cursor the observer is registered with. */ // 是否传递自己的改变 @Overridepublic boolean deliverSelfNotifications() {return super.deliverSelfNotifications();}// 当被监听的内容发生了改变时,调用该方法 @Overridepublic void onChange(boolean selfChange) {Log.i("MainActivity", "监听到了变化!!");//打印最后插入的信息ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student");//select * from student order by id desc limit 1Cursor c = resolver.query(uri, null, null, null, " id desc limit 1");if(c.moveToNext()){String string = "id="+ c.getInt(0) + ",name=" + c.getString(1) + ",address=" + c.getString(2);Log.i("MainActivity", string);Toast.makeText(MainActivity.this, string, 1).show();}//父类未做任何操作super.onChange(selfChange);}};Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student");getContentResolver().registerContentObserver(uri, true, observer);}

View Code

九、监听内容提供者实例,三个应用来完成,注意:测试这个监听数据变化不能用单元测试来完成,因为但点击单元测试完成后,应用自动关闭了。

内容提供者,就用contentprovider工程,另外在创建aprovidertest和bprovidertest工程。如图:

1.aprovidertest中的代码

activity_app.xml

<RelativeLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"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=".AppActivity" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="test provider A" /><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_centerVertical="true"android:onClick="insert"android:text="Button" /></RelativeLayout>

View Code

AppActivity.java

package com.bruce.eoe.provider;import .Uri;import android.os.Bundle;import android.app.Activity;import android.content.ContentResolver;import android.content.ContentValues;import android.util.Log;import android.view.Menu;import android.view.View;public class AppActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_app);}public void insert(View v){ContentResolver resolver = this.getContentResolver();Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student");ContentValues values = new ContentValues();values.put("name", "发哥");values.put("address", "香港");resolver.insert(uri, values);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.app, menu);return true;}}

View Code

2.bprovidertest中的代码

MainActivity.java

package com.bruce.bprovidertest;import android.app.Activity;import android.content.ContentResolver;import android.database.ContentObserver;import android.database.Cursor;import .Uri;import android.os.Bundle;import android.os.Handler;import android.util.Log;import android.view.Menu;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student");ContentResolver resolver = this.getContentResolver();resolver.registerContentObserver(uri, true, new MyContentObserver(new Handler()));}private class MyContentObserver extends ContentObserver{public MyContentObserver(Handler handler) {super(handler);}// 得到数据的变化通知,该方法只能粗略知道数据的改变,并不能判断是哪个业务操作进行的改变 @Override public void onChange(boolean selfChange) { // select * from person order by id desc limit 1 // 取得最近插入的值(序号大——>小并取第一个) Uri uri = Uri.parse("content://com.bruce.contentprovider.demo/student"); ContentResolver resolver = MainActivity.this.getContentResolver(); Cursor cursor = resolver.query(uri, null, null, null, "id desc limit 1"); if(cursor.moveToFirst()) { String string = "id=" + cursor.getInt(0) + ",name=" + cursor.getString(1) + ",address=" + cursor.getString(2); Log.i("MyTest", string); } } }@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}}

View Code

首先运行contentprovider工程,在运行bprovidertest工程,然后再运行aprovidertest工程,点击Button按钮,就可以向contentprovider工程中插入数据,然后bprovidertest中可以监听到数据变化。

测试时,或许会提示:java.lang.SecurityException: Permission Denial: opening provider 异常,在AndroidManifest.xml文件中的provider节点中加入 android:exproted = "true" 即可解决。

<provider

android:name="com.bruce.contentprovider.demo.MyContentProvider"

android:authorities="com.bruce.contentprovider.demo"

android:exported="true"

></provider>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。