ContentProvider组件就是为了不同进程之间共享数据而存在的,如果是自己写的应用程序之间共享数据我个人反而觉得用ContentProvider比较麻烦,可能是我没学过数据库的原因吧,很多SQL语句看起来好别扭的感觉,待我大三开学学完数据库再来温习一次可能就有不同的感触了。
首先搞清楚这个组件的原理,它需要继承ContentProvider类,重写onCreate(),insert(),delete(),query(),update()等方法,明显是专门的为SQLite服务了。然后在AndroidManifest.xml那里配置这个组件,提供ContentProvider这边的应用就完事了。
另一个应用想要使用提供ContentProvider的应用的数据时,只需要ContentResolver cr=getContentResolver();然后调用cr.insert(),cr.delete()这些函数就行了,参数与provider那边的函数参数一致的。
下面就以我探究了一个下午才搞起来的2个应用程序举个简单的例子,绝对比起好多网上的例子简单,因为我看不明白别人那个Uri的分析,大体上知道怎么回事,但是叫我自己编还是不会,主要还是数据库那边看不明,所以无从入手了,唯有弄个简单的例子了。
首先用回我上一遍博客的SQLite的数据库:_id(integer) username(text) password(text)这个是列的属性,以及列的类型,已经建立了一个叫UserTb1的表了,并且里面存有一些记录了。
首先在提供者这边的Project:
package com.example.sqlitetest;
import java.io.File;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Environment;
import android.widget.Toast;
public class MyProvider extends ContentProvider
{
private SQLiteDatabase db;
@Override
public int delete(Uri arg0, String arg1, String[] arg2)
{
// TODO Auto-generated method stub
db.delete("UserTb1", arg1, arg2);
System.out.println("provider delete");
return 0;
}
@Override
public String getType(Uri arg0)
{
// TODO Auto-generated method stub
System.out.println("provider getType");
return null;
}
@Override
public Uri insert(Uri arg0, ContentValues arg1)
{
// TODO Auto-generated method stub
db.insert("UserTb1", null, arg1);
System.out.println("provider insert");
return null;
}
@Override
public boolean onCreate()
{
// TODO Auto-generated method stub
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
File sdcardDir=Environment.getExternalStorageDirectory();
File dbfile=new File(sdcardDir, "database.db");
db=SQLiteDatabase.openOrCreateDatabase(dbfile, null);
}
System.out.println("provider create");
return false;
}
@Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
String arg4)
{
// TODO Auto-generated method stub
return db.query("UserTb1", null, null, null, null, null, null);
//System.out.println("provider query");
//return null;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3)
{
// TODO Auto-generated method stub
db.update("UserTb1", arg1, arg2, arg3);
System.out.println("provider update");
return 0;
}
}
然后配置好它:注意authorities属性就是以后要用到的Uri了,exported要为true才能为其他应用服务的。
<provider
android:name=".MyProvider"
android:authorities="com.example.sqlitetest.myprovider"
android:exported="true"></provider>
至于怎样使用这个Provider,只要在其他应用程序中:
ContentResolver cr=getContentResolver();
Uri uri=Uri.parse("content://com.example.sqlitetest.myprovider/");
//插入数据
/*ContentValues values=new ContentValues();
values.put("username", "pear");
values.put("password", "777");
cr.insert(uri, values);*/
//删除数据
/*String where="_id=?";
String whereArgs[]={String.valueOf(2)};
cr.delete(uri, where, whereArgs);*/
//更新数据
/*ContentValues values=new ContentValues();
values.put("password", "888");
String where="username=?";
String whereArgs[]={"banana"};
cr.update(uri, values, where, whereArgs);*/
Cursor cursor=cr.query(uri, null, null, null, null);
String res=new String();
/*for(int i=0;i<cursor.getCount();i++)
{
res+=cursor.getInt(0)+" ";
res+=cursor.getString(1)+" ";
res+=cursor.getString(2)+" \n";
}*/
if(cursor.moveToFirst())
{
for(int i=0;i<cursor.getCount();i++)
{
res+=cursor.getInt(0)+" ";
res+=cursor.getString(1)+" ";
res+=cursor.getString(2)+" \n";
cursor.moveToNext();
}
}
TextView showTextView=(TextView)findViewById(R.id.show);
showTextView.setText(res);
感觉这个组件应该还是主要用于获取系统应用的Provider的,例如获取联系人电话之类的,因此必须要查阅官方资料看系统的那些数据库表的列的值和类型才能获取它们。