Contentprovider学习笔记

  当应用程序的数据需要被别的应用程序使用时,就必须将应用程序的数据抛出,通常要继承contentprovider类,并且覆写它的方法。下面通过将数据库的数据抛出例子学习一下:

1首先我们必须在应用程序的清单文件里配置provider:

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        <uses-library android:name="android.test.runner" />
        <activity
            android:name="com.example.database.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <provider android:name="com.mydatabase.provider.Personprovider"
                    android:authorities="com.mydatabase.personprovider"
             >
        </provider>
        
    </application>

  其中name属性是provider的包名下具体类名,authorities是主机名,是标识这个应用程序的provider的,通常以功能命名(没有具体规范),在uri的匹配时会用到(后面会讲到)。

 

  2实现一个继承contentprovider的类,为了抛出数据和操作数据的方法,android提供了Urimather来实现uri的匹配。contentprovider抛出的数据在别的应用程序里利用contentresolver绑定这唯一的uri来对数据操作的:

 

public class Personprovider extends ContentProvider {

    public static final UriMatcher matcher =new UriMatcher(UriMatcher.NO_MATCH);
    Mydatebase dbhelper;
    public static final Uri baseuri=Uri.parse("com.mydatabase.personprovider");//被监听的uri
    public static final int  ALL_PERSON=1;
    static
    {
        matcher.addURI("com.mydatabase.personprovider", "query", ALL_PERSON);//红色部分是主机名,后面的是路径,在后面query/#or*,#表示数字,*表示任意字符
    }
    
    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        dbhelper=new Mydatebase(getContext());
//        SQLiteDatabase db=dbhelper.getReadableDatabase();
                
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        int result=matcher.match(uri);
        Cursor cur=null;
        if(result==ALL_PERSON)//匹配成功时返回的是ALL_PERSON的值
        {
        SQLiteDatabase db=dbhelper.getWritableDatabase();
        cur=db.query("person", projection, selection, selectionArgs, null, null, null);
        return cur;
        }
        else
        {
            throw new IllegalArgumentException("无法找到匹配对象!");
        }
    }

  public Uri insert(Uri uri, ContentValues values) {

  int result =matcher.match(uri);
  if(result==ADD)
  {
  SQLiteDatabase db=dbhelper.getWritableDatabase();
  db.insert("person", null, values);
  getContext().getContentResolver().notifyChange(baseuri, null);//发生插入时候告诉baseuri,第二个参数是监听器,为空则只有在外面设置监听器通过uri获取信息,不为空则向指定的观察者发出通知

  }

  return null;
  }

 

public String getType(Uri uri) {
// TODO Auto-generated method stub
int result=matcher.match(uri);
if(result==ALL_PERSON)
return "vnd.android.cursor.dir/Person";//一条数据,如果是多条数据vnd.android.cursor.item/person

return null;
}


 

 3、在别的应用里只需要获取contentresolver,然后带入相应的uri来对数据进行操作:(下面代码是通过一个button按钮获取数据库内person表的数据)

public void click(View View)
{
    Uri uri=Uri.parse("content://com.mydatabase.personprovider/query");
    ContentResolver rs=getContentResolver();
//    rs.query(uri, null, selection, selectionArgs, sortOrder)
    Cursor cur=rs.query(uri, null, null, null, null);
    
    while(cur.moveToNext())
    {
        System.out.println(cur.getString(0));
        
    }
    
}

 4、我们可以为数据库设定内容监听者,或者说监听器,在实现provider时当数据库内数据发生改变时就调用getContext().getContentResolver().notifyChange(uri, observer);他会将改变信息告诉相对应的uri,然后再别的程序里设定监听器只要监听该uri就可以知道数据库发生了改变。

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Uri uri=Uri.parse("com.mydatabase.personprovider");
        getContentResolver().registerContentObserver(uri, true, new obs(new Handler()));//第二个参数为true时候表示只要是baseuri这个目录发生改变都会监听到//,false时必须uri必须是baseuri后的具体改变的uri,第三个是监听器,需要实现下面是简单的实现方式
    }
public class obs extends ContentObserver
{

	public obs(Handler handler) {
		super(handler);
		// TODO Auto-generated constructor stub
	}
	 public void onChange(boolean selfChange) {
	        // Do nothing.  Subclass should override.
		 System.out.println("数据发生改变了!");//数据发生改变后的操作
	 }
	
}

  

posted @ 2015-08-06 11:48  Lammy  阅读(251)  评论(0编辑  收藏  举报