一、什么情况下需要使用内容提供器?
内容提供器用来存放和获取数据并使这些数据可以被所有的应用程序访问。它们是应用程序之间共享数据的唯一方法,不存在所有Android软件包都能访问的公共储存区域。
Android为常见数据类型(音频,视频,图像,个人联系人信息,等等)装载了很多内容提供器,在android.provider包里列举了一些。可以查询这些提供器包含了什么数据(尽管,对某些提供器,必须获取合适的权限来读取数据)。
如果开发者想公开应用程序自己的数据,有两个选择:创建自己的内容提供器(一个ContentProvider子类) 或者 给已有的提供器添加数据(前提是存在一个控制同样类型数据的内容提供器且你拥有写的权限)。
二、如何创建内容提供器?
要创建一个内容提供器,你必须:
1)建立一个保存数据的系统。大多数内容提供器使用Android的文件储存方法或SQLite数据库来存放它们的数据,但是你可以用任何你想要的方式来存放数据。Android提供SQLiteOpenHelper类来帮助你创建一个数据库以及SQLiteDatabase类来管理它。
2)扩展ContentProvider类来提供数据访问接口。
3)在清单manifest文件中为你的应用程序声明这个内容提供器(AndroidManifest.xml)。
三、content URI的重要内容
A. 标准前缀表明这个数据被一个内容提供器所控制。它不会被修改。
B. URI的权限部分;它标识这个内容提供器。对于第三方应用程序,这应该是一个全称类名(小写)以确保唯一性。权限在<provider>元素的权限属性中进行声明:
<provider name=".TransportationProvider"
authorities="com.example.transportationprovider"
. . . >
C. 用来判断请求数据类型的路径。这可以是0或多个段长。如果内容提供器只暴露了一种数据类型(比如,只有火车),这个分段可以没有。如果提供器暴露若干类型,包括子类型,那它可以是多个分段长-例如,提供"land/bus","land/train", "sea/ship", 和"sea/submarine"这4个可能的值。
D. 被请求的特定记录的ID,如果有的话。这是被请求记录的_ID数值。如果这个请求不局限于单个记录,这个分段和尾部的斜线会被忽略:
content://com.example.transportationprovider/trains
四、例子
第一步:创建数据保存系统
/**
* 数据库操作帮助类 安装版本:SDSQLiteOpenHelper
* 模拟测试版本 :SQLiteOpenHelper
*
* @author Jessica
* @date 2013-5-18
*/
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "info.db";
private static final String TABLE_CREATE = "CREATE TABLE info "
+ "(_id INTEGER PRIMARY KEY, zc_code1 TEXT,zc_code2 TEXT, zc_nums TEXT);";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.v("DatabaseHelper","----create database end---------");
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.v("DatabaseHelper","----create table begin --------");
db.execSQL(TABLE_CREATE);
Log.v("DatabaseHelper","----create table end --------");
Log.v("DatabaseHelper","----init data begin --------");
db.execSQL("insert into info values(1,'BX','CD','10A');");
db.execSQL("insert into info values(2,'BX','CD','10B');");
Log.v("DatabaseHelper","----init data end --------");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion != oldVersion) {
db.execSQL("DROP TABLE IF EXISTS info");
onCreate(db);
}
Log.v("DatabaseHelper","----update database end --------");
}
}
第二步:扩展ContentProvider类,提供数据访问接口
public class InfoProvider extends ContentProvider {
private static final String INFO_TABLE_NAME = "info";
private static final int INFOS = 1;
private DatabaseHelper mOpenHelper;
private static final UriMatcher sUriMatcher;
/*
* 创建数据库
*
* @see android.content.ContentProvider#onCreate()
*/
@Override
public boolean onCreate() {
mOpenHelper = new DatabaseHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
switch (sUriMatcher.match(uri)) {
case INFOS:
qb.setTables(INFO_TABLE_NAME);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
// Get the database and run the query
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
if (sortOrder != null) {
Cursor c = qb.query(db, projection, selection, selectionArgs, sortOrder, null, null);
return c;
}
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, null);
return c;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(Info.AUTHORITY, "info", INFOS);
}
}
第三步:使用数据访问接口
public class MainActivity extends Activity {
private Intent intent;
public static final String[] infoProjection = new String[] { Infos._ID, Infos.CODE1, Infos.CODE2,
Infos.NUMS };
EditText txtCode1 = null;
EditText txtCode2 = null;
EditText txtNums = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtCode1 = (EditText) this.findViewById(R.id.txt_code1);
txtCode2 = (EditText) this.findViewById(R.id.txt_code2);
txtNums = (EditText) this.findViewById(R.id.txt_nums);
intent = getIntent();
// 初始化数据
this.initData();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void initData() {
intent.setData(Infos.CONTENT_URI);
Cursor c = managedQuery(getIntent().getData(), infoProjection, null, null, null);
if (c.getCount() != 0) {
c.moveToFirst();
while (!c.isLast()) {
txtCode1.setText(c.getString(c.getColumnIndex(Infos.CODE1)));
txtCode2.setText(c.getString(c.getColumnIndex(Infos.CODE2)));
txtNums.setText(c.getString(c.getColumnIndex(Infos.NUMS)));
c.moveToNext();
}
}
}
}