ContentProvider在安卓开发中非常重要。与Activity,Service,BroadcastReceiver并称安卓组件四大天王。
在android中的作用是用来对外共享数据。因为安卓程序的数据库文件存放在data/data/packagename里面,这里面的文件默认都是私有的,别的程序无法访问。
如果QQ游戏想访问手机QQ的帐号信息一键登录,那么就需要使用内容提供者COntentPrivoder来访问。
最常用的就是开发一个程序读取系统的联系人。
实现步骤:
1、写好数据库的增删改查。
package com.hb.db;
import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.hb.bean.User;
public class DBHelp extends SQLiteOpenHelper {
public DBHelp(Context context) {
super(context, "Test", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "create table users (_id integer primary key autoincrement,name text,phone text)";
db.execSQL(createTable);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void add(User user) {
SQLiteDatabase database = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", user.getName());
values.put("phone", user.getPhone());
database.insert("users", null, values);
database.close();
}
public void delete(User user) {
SQLiteDatabase database = getWritableDatabase();
database.delete("users", "name = ? or phone = ?",
new String[] { user.getName(), user.getPhone() + "" });
database.close();
}
public ArrayList<User> getData() {
ArrayList<User> list = new ArrayList<User>();
// 获得所有的数据
String sql = "select * from users";
SQLiteDatabase sdb = this.getReadableDatabase();
Cursor cursor = sdb.rawQuery(sql, null);
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String phone = cursor.getString(2);
list.add(new User(Long.parseLong(phone), name));
}
cursor.close();
sdb.close();
return list;
}
}
2、写内容提供者MyProvider继承ContentProvider,使用静态块初始化UriMatcher,重写ContentProvider里面的6个方法
static {
matcher = new UriMatcher(UriMatcher.NO_MATCH);
// 查询
matcher.addURI("com.hb.provider", "get", 10);
// 插入
matcher.addURI("com.hb.provider", "insert", 20);
// 删除
matcher.addURI("com.hb.provider", "delete/#", 30);
}
只实现了delete,querry,insert方法,update类似
package com.hb.provider;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import com.hb.db.DBHelp;
public class MyProvider extends ContentProvider {
static UriMatcher matcher;
static {
matcher = new UriMatcher(UriMatcher.NO_MATCH);
// 查询
matcher.addURI("com.hb.provider", "get", 10);
// 插入
matcher.addURI("com.hb.provider", "insert", 20);
// 删除
matcher.addURI("com.hb.provider", "delete/#", 30);
}
@Override
public boolean onCreate() {
return true;
}
/**
* uri,要查询的字段名,where条件,where语句中?的值,排序字段
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int code = matcher.match(uri);
Log.i("Test", code + "");
switch (code) {
case 10:
DBHelp db = new DBHelp(getContext());
Cursor cursor = db.getReadableDatabase().rawQuery(
"select * from users", null);
return cursor;
}
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int code = matcher.match(uri);
switch (code) {
case 20:
DBHelp db = new DBHelp(getContext());
long id = db.getWritableDatabase().insert("users", null, values);
return ContentUris.withAppendedId(uri, id);
}
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int code = matcher.match(uri);
switch (code) {
case 30:
DBHelp db = new DBHelp(getContext());
int id = db.getWritableDatabase().delete("users", selection,
selectionArgs);
return id;
}
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return 0;
}
}
一定要记得在AndroidMenifest清单文件里注册,它和Activity一样,放在Application节点下
<provider
android:name="com.hb.provider.MyProvider"
android:authorities="com.hb.provider" >
</provider>
此时,内容提供者就已经写好了。再写另外一个程序对其数据库进行操作。
3、写其他程序访问内容提供者
在Activity里面,可以使用context调用getContentResolver()方法得到ContentResolver resolver = getContentResolver();
,之后就可以使用resolver对数据库进行操作了。
首先,会根据uri找到对应的应用程序,再根据insert之类的子命令找到对应定义号的code(20),执行MyProvider里面的insert方法。其中uri中的“content://”是内容提供者的固定写法。
package com.example.testprovider;
import java.util.ArrayList;
import com.hb.bean.User;
import
android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import
android.view.View;
public class MainActivity extends Activity {
private ContentResolver resolver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate
(savedInstanceState);
setContentView(R.layout.activity_main);
resolver =
this.getContentResolver();
}
public void delete(View v) {
Uri uri = Uri.parse
("content://com.hb.provider/delete/1");
// 删除phone为123的人
int count = resolver.delete
(uri, "phone = ?",
new String[] { "123" });
Log.i("Test", count +
"条数据被删除");
}
public void querry(View v) {
Uri uri = Uri.parse
("content://com.hb.provider/get");
Cursor cursor =
resolver.query(uri, null, null, null, null);
if (cursor != null) {
ArrayList<User> list = new ArrayList<User>();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String phone = cursor.getString(2);
list.add(new User(Long.parseLong(phone), name));
}
Log.i("Test", list.toString());
} else {
Log.i("Test", "没查到");
}
}
public void insert(View v) {
Uri uri = Uri.parse
("content://com.hb.provider/insert");
ContentValues values = new ContentValues();
values.put("name", "name");
values.put("phone", "111");
resolver.insert(uri, values);
}
}