Android内容提供者(二)创建自己的Provider
2016-06-23 15:20
411 查看
为什么要使用内容提供者呢?Android考虑到程序之间的通信。如果使用以前的方式保存数据,然后用一个全局的操作权限去访问,这对数据的安全性和保密性造成了极大的影响。通过内容提供者来共享数据,就能很好的解决掉这些问题,它可以指定一些数据共享,并且可以指定操作,像增删查改。比如某个程序只允许用户查看数据,不允许用户修改数据。那就只要实现内容提供者里面的查询函数就可以了。
一.自定义ContentProvider必备条件
1.数据库辅助类,用来实现数据的存储。内容提供者提供的内容都是从数据库中读取的。
2.uri匹配项
其他程序要访问ContentProvider,是通过uri解析得到的。从另一个方面讲,就是ContentProvider必须知道其他程序要操作的是哪个表的哪一项。UriMatcher这个类就是了uri的匹配。添加以下代码:
上面定义了PERSON_DIR是值操作tb_person的全部数据,PERSON_ITEM 是操作tb_person的某项数据。
AUTHORITY 是uri匹配的前缀,一般都是使用包名来和其他的ContentProvider来区分。从上面来看,添加两条可以匹配的uri
二、创建自定义ContentProvider
完成这些操作之后,先运行程序,让本程序在模拟器中运行起来,然后在新建一个工程ProviderTest来测试定义的ContentProvider是否可用。
1.修改主布局
2.为每一个选项添加具体操作
逐步点击上面的按钮,用sqlite3.exe查看结果即可。
项目地址:明天更新
心记不如淡墨,哈哈。
一.自定义ContentProvider必备条件
1.数据库辅助类,用来实现数据的存储。内容提供者提供的内容都是从数据库中读取的。
public class DbHelper extends SQLiteOpenHelper { private static final String CREATE_PERSON_TABLE = "create table tb_person (" + "id integer primary key autoincrement, " + "name varchar(16), " + "info text)"; public DbHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub db.execSQL(CREATE_PERSON_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } }
2.uri匹配项
其他程序要访问ContentProvider,是通过uri解析得到的。从另一个方面讲,就是ContentProvider必须知道其他程序要操作的是哪个表的哪一项。UriMatcher这个类就是了uri的匹配。添加以下代码:
public static final int PERSON_DIR = 0; public static final int PERSON_ITEM = 1; public static final String AUTHORITY = "com.example.custom.provider"; private DbHelper mDbHelper; private static UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "tb_person", PERSON_DIR); uriMatcher.addURI(AUTHORITY, "tb_person/#", PERSON_ITEM); }
上面定义了PERSON_DIR是值操作tb_person的全部数据,PERSON_ITEM 是操作tb_person的某项数据。
AUTHORITY 是uri匹配的前缀,一般都是使用包名来和其他的ContentProvider来区分。从上面来看,添加两条可以匹配的uri
二、创建自定义ContentProvider
public class PersonProvider extends ContentProvider {
public static final int PERSON_DIR = 0; public static final int PERSON_ITEM = 1; public static final String AUTHORITY = "com.example.custom.provider"; private DbHelper mDbHelper; private static UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "tb_person", PERSON_DIR); uriMatcher.addURI(AUTHORITY, "tb_person/#", PERSON_ITEM); }
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
mDbHelper = new DbHelper(getContext(), "person.db", null, 1);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Cursor cursor = null;
switch (uriMatcher.match(uri)) {
case PERSON_DIR:
// 查询tb_person的所有数据
cursor = db.query("tb_person", projection, selection,
selectionArgs, null, null, sortOrder);
break;
case PERSON_ITEM:
// 查询tb_person的某一项数据
String personId = uri.getPathSegments().get(1);
cursor = db.query("tb_person", projection, "id = ?",
new String[] { personId }, null, null, sortOrder);
break;
default:
break;
}
return cursor;
}
@Override
public String getType(Uri uri) {
//
4000
TODO Auto-generated method stub
switch (uriMatcher.match(uri)) {
case PERSON_DIR:
// 查询tb_person的所有数据
return "vnd.android.cursor.dir/vnd.com.example.custom.provider.tb_person";
case PERSON_ITEM:
// 查询tb_person的某一项数据
return "vnd.android.cursor.item/vnd.com.example.custom.provider.tb_person";
default:
return null;
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
SQLiteDatabase db = mDbHelper.getWritableDatabase();
Uri uriRet = null;
switch (uriMatcher.match(uri)) {
case PERSON_DIR:
case PERSON_ITEM:
long personId = db.insert("tb_person", null, values);
uriRet = Uri.parse("content://" + AUTHORITY + "/tb_person/"
+ personId);
default:
break;
}
return uriRet;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int deletedRows = 0;
switch (uriMatcher.match(uri)) {
case PERSON_DIR:
deletedRows = db.delete("tb_person", selection, selectionArgs);
break;
case PERSON_ITEM:
String personId = uri.getPathSegments().get(1);
deletedRows = db.delete("tb_person", "id = ?",
new String[] { personId });
break;
}
return deletedRows;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int updatedRows = 0;
switch (uriMatcher.match(uri)) {
case PERSON_DIR:
updatedRows = db.update("tb_person", values, selection,
selectionArgs);
break;
case PERSON_ITEM:
String personId = uri.getPathSegments().get(1);
updatedRows = db.update("tb_person", values, "id = ?",
new String[] { personId });
break;
}
return updatedRows;
}
}
完成这些操作之后,先运行程序,让本程序在模拟器中运行起来,然后在新建一个工程ProviderTest来测试定义的ContentProvider是否可用。
1.修改主布局
<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" > <Button android:id="@+id/insert" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="insert" /> <Button android:id="@+id/delete" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="delete" /> <Button android:id="@+id/update" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="update" /> <Button android:id="@+id/select" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="select" /> </LinearLayout>
2.为每一个选项添加具体操作
public class MainActivity extends Activity { private String insertId = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button insert = (Button) findViewById(R.id.insert); insert.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Uri uri = Uri .parse("content://com.example.custom.provider/tb_person"); ContentValues values = new ContentValues(); values.put("name", "hehe"); values.put("info", "123456"); Uri insertUri = getContentResolver().insert(uri, values); insertId = insertUri.getPathSegments().get(1); } }); Button update = (Button) findViewById(R.id.update); update.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Uri uri = Uri .parse("content://com.example.custom.provider/tb_person/" + insertId); ContentValues values = new ContentValues(); values.put("info", "123456789"); getContentResolver().update(uri, values, null, null); } }); Button delete = (Button) findViewById(R.id.delete); delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Uri uri = Uri .parse("content://com.example.custom.provider/tb_person"); getContentResolver().delete(uri, null, null); } }); Button select = (Button) findViewById(R.id.select); select.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Uri uri = Uri .parse("content://com.example.custom.provider/tb_person"); Cursor cursor = getContentResolver().query(uri, null, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { String name = cursor.getString(cursor .getColumnIndex("name")); String info = cursor.getString(cursor .getColumnIndex("info")); Log.i("info", name + " " + info); } cursor.close(); } } }); } }
逐步点击上面的按钮,用sqlite3.exe查看结果即可。
项目地址:明天更新
心记不如淡墨,哈哈。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories