Android-ContentProvider 实例详解 (1)
实例代码:
ContentResolver resolver = ?getContentResolver();
Uri uri = Uri.parse("content://cn.scu.myprovider/user");
//添加一条记录
ContentValues values = new ContentValues();
values.put("name", "fanrunqi");
values.put("age", 24);
resolver.insert(uri, values); ?
//获取 user 表中所有记录
Cursor cursor = resolver.query(uri, null, null, null, "userid desc");
while(cursor.moveToNext()){
//操作
}
//把 id 为 1 的记录的 name 字段值更改新为 finch
ContentValues updateValues = new ContentValues();
updateValues.put("name", "finch");
Uri updateIdUri = ContentUris.withAppendedId(uri, 1);
resolver.update(updateIdUri, updateValues, null, null);
//删除 id 为 2 的记录
Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);
resolver.delete(deleteIdUri, null, null);
5?ContentObserver
ContentObserver(内容观察者),目的是观察特定 Uri 引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当 ContentObserver 所观察的 Uri 发生变化时,便会触发它.
下面是使用内容观察者监听短信的例子:
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//注册观察者 Observser ? ?this.getContentResolver().registerContentObserver(Uri.parse("content://sms"),true,new SMSObserver(new Handler()));}private final class SMSObserver extends ContentObserver {public SMSObserver(Handler handler) {super(handler);}@Overridepublic void onChange(boolean selfChange) {Cursor cursor = MainActivity.this.getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null);while (cursor.moveToNext()) {StringBuilder sb = new StringBuilder();sb.append("address=").append(cursor.getString(cursor.getColumnIndex("address")));sb.append(";subject=").append(cursor.getString(cursor.getColumnIndex("subject")));sb.append(";body=").append(cursor.getString(cursor.getColumnIndex("body")));sb.append(";time=").append(cursor.getLong(cursor.getColumnIndex("date")));System.out.println("--------has Receivered SMS::" + sb.toString());}}}}
同时可以在 ContentProvider 发生数据变化时调用?getContentResolver().notifyChange(uri, null)来通知
注册在此 URI 上的访问者。
public class UserContentProvider extends ContentProvider {
public Uri insert(Uri uri, ContentValues values) {
db.insert("user", "userid", values);
getContext().getContentResolver().notifyChange(uri, null);
}
}
##6 ?实例说明
数据源是 SQLite, 用 ContentResolver 操作 ContentProvider。
Constant.Java(储存一些常量)
public class Constant { ?
public static final String TABLE_NAME = "user"; ?
public static final String COLUMN_ID = "_id"; ?
public static final String COLUMN_NAME = "name"; ?
public static final String AUTOHORITY = "cn.scu.myprovider"; ?
public static final int ITEM = 1; ?
public static final int ITEM_ID = 2; ?
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/user"; ?
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/user"; ?
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTOHORITY + "/user"); ?
} ?
DBHelper.java(操作数据库)
public class DBHelper extends SQLiteOpenHelper { ?
private static final String DATABASE_NAME = "finch.db"; ? ?
private static final int DATABASE_VERSION = 1; ? ?
public DBHelper(Context context) { ?
super(context, DATABASE_NAME, null, DATABASE_VERSION); ?} ?
@Override ?
public void onCreate(SQLiteDatabase db) ?throws SQLException { ?
//创建表格 ?
db.execSQL("CREATE TABLE IF NOT EXISTS "+ Constant.TABLE_NAME + "("+ Constant.COLUMN_ID +" INTEGER PRIMARY KEY AUTOINCREMENT," + Constant.COLUMN_NAME +" VARCHAR NOT NULL);"); ?
} ?
@Override ?
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) ?throws SQLException { ?
//删除并创建表格 ?
db.execSQL("DROP TABLE IF EXISTS "+ Constant.TABLE_NAME+";"); ?
onCreate(db); ?
} ?
} ?
MyProvider.java(自定义的 ContentProvider)
public class MyProvider extends ContentProvider { ? ?
DBHelper mDbHelper = null; ? ?
SQLiteDatabase db = null; ? ?
private static final UriMatcher mMatcher; ? ?
static{ ? ?
mMatcher = new UriMatcher(UriMatcher.NO_MATCH); ? ?mMatcher.addURI(Constant.AUTOHORITY,Constant.TABLE_NAME, Constant.ITEM); ? ?
mMatcher.addURI(Constant.AUTOHORITY, Constant.TABLE_NAME+"/#", Constant.ITEM_ID); ? ?
} ? ?
@Override ? ?
public String getType(Uri uri) { ? ?
switch (mMatcher.match(uri)) { ? ?
case Constant.ITEM: ? ?
return Constant.CONTENT_TYPE; ? ?
case Constant.ITEM_ID: ? ?
return Constant.CONTENT_ITEM_TYPE; ? ?
default: ? ?
throw new IllegalArgumentException("Unknown URI"+uri); ? ?
} ? ?
} ? ?
@Override ? ?
public Uri insert(Uri uri, ContentValues values) { ? ?
// TODO Auto-generated method stub ? ?
long rowId; ? ?
if(mMatcher.match(uri)!=Constant.ITEM){ ? ?
throw new IllegalArgumentException("Unknown URI"+uri); ? ?
} ? ?
rowId = db.insert(Constant.TABLE_NAME,null,values); ? ?
if(rowId>0){ ? ?
Uri noteUri=ContentUris.withAppendedId(Constant.CONTENT_URI, rowId); ? ?
getContext().getContentResolver().notifyChange(noteUri, null); ? ?
return noteUri; ? ?
} ? ?
throw new SQLException("Failed to insert row into " + uri); ? ?
} ? ?
@Override ? ?
public boolean onCreate() { ? ?
// TODO Auto-generated method stub ? ?
mDbHelper = new DBHelper(getContext()); ? ?
db = mDbHelper.getReadableDatabase(); ? ?
return true; ? ?
} ? ?
@Override ? ?
public Cursor query(Uri uri, String[] projection, String selection, ? ?
String[] selectionArgs, String sortOrder) { ? ?
// TODO Auto-generated method stub ? ?
Cursor c = null; ? ?
switch (mMatcher.match(uri)) { ? ?
case Constant.ITEM: ? ?
c = ?db.query(Constant.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); ? ?
break; ? ?
case Constant.ITEM_ID: ? ?
c = db.query(Constant.TABLE_NAME, projection,Constant.COLUMN_ID + "="+uri.getLastPathSegment(), selectionArgs, null, null, sortOrder); ? ?
break; ? ?
default: ? ?
throw new IllegalArgumentException("Unknown URI"+uri); ? ?
} ? ?
c.setNotificationUri(getContext().getContentResolver(), uri); ? ?
return c; ? ?
} ? ?
@Override ? ?
public int update(Uri uri, ContentValues values, String selection, ? ?
String[] selectionArgs) { ? ?
// TODO Auto-generated method stub ? ?
return 0; ? ?
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
} ? ?
} ? ?
MainActivity.java(ContentResolver 操作)
public class MainActivity extends Activity {
private ContentResolver mContentResolver = null;?
private Cursor cursor = null; ?
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.tv);
mContentResolver = getContentResolver(); ?
tv.setText("添加初始数据 ");
for (int i = 0; i < 10; i++) { ?
ContentValues values = new ContentValues(); ?
values.put(Constant.COLUMN_NAME, "fanrunqi"+i); ?
mContentResolver.insert(Constant.CONTENT_URI, values); ?
}?
tv.setText("查询数据 ");
cursor = mContentResolver.query(Constant.CONTENT_URI, new String[]{Constant.COLUMN_ID,Constant.COLUMN_NAME}, null, null, null); ?
if (cursor.moveToFirst()) {
String s = cursor.getString(cursor.getColumnIndex(Constant.COLUMN_NAME));
tv.setText("第一个数据: "+s);
}
}
} ?
最后在 manifest 申明
<provider android:name="MyProvider" android:authorities="cn.scu.myprovider" />
【附】相关架构及资料
资料领取
点赞+加群免费获取?Android IOC架构设计
加群领取获取往期 Android 高级架构资料、源码、笔记、视频。高级 UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter 全方面的 Android 进阶实践技术,群内还有技术大牛一起讨论交流解决问题。
评论