您的位置:首页 > 移动开发 > Android开发

Android内容提供者(二)创建自己的Provider

2016-06-23 15:20 411 查看
为什么要使用内容提供者呢?Android考虑到程序之间的通信。如果使用以前的方式保存数据,然后用一个全局的操作权限去访问,这对数据的安全性和保密性造成了极大的影响。通过内容提供者来共享数据,就能很好的解决掉这些问题,它可以指定一些数据共享,并且可以指定操作,像增删查改。比如某个程序只允许用户查看数据,不允许用户修改数据。那就只要实现内容提供者里面的查询函数就可以了。

一.自定义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查看结果即可。

项目地址:明天更新

心记不如淡墨,哈哈。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 内容提供者