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); } }