有时候我们需要动态的刷新页面,比如收到短信的时候,短信页面动态刷新,显示最新的短信状态。
一般我们会采用监听数据库的方法来实现,但是监听数据库要有uri,也就是要tigongContentProvider才行。
这里就是一个简单里的例子,输入姓名,点插入按钮就会插入数据,然后动态更新下面的TextView,点击删除按钮也会更新TextView。
不多说了,让代码来说话。
DBInfo.java:
public class DBInfo implements BaseColumns{
private DBInfo() {}
public static final String AUTHORITY = "droid.provider.mycontentprovider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/my_tbl");
public static final String CONTENT_TYPE = "vnd.Android.cursor.dir/vnd.droid.my_tbl";
public static final String CONTENT_ITEM_TYPE = "vnd.Android.cursor.item/vnd.droid.my_tbl";
public static final String TABLE_NAME = "my_tbl";
public static final int VERSION = 1;
public static final String NAME = "name";
}
DatabaseHelper.java:
public class DatabaseHelper extends SQLiteOpenHelper {
public static String DATABASE_NAME = "mydatabase.db";
public static int version = 1;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, version);
}
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
}
@Override
public void onCreate(SQLiteDatabase db) {
String s = "CREATE TABLE " + DBInfo.TABLE_NAME +
" (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)";
db.execSQL(s);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS notes");
onCreate(db);
}
}
上面两个类定义了一些数据库的结构,和一些常量等。
下面是ContentProvider(没有实现完全,只是先部分方法):
public class MyContentProvider extends ContentProvider {
private static final int ALL_ROWS = 1;
private static final int SINGLE_ROW = 2;
private static UriMatcher uriMatcher = null;
private DatabaseHelper dbHelper = null;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(DBInfo.AUTHORITY, "my_tbl", ALL_ROWS);
uriMatcher.addURI(DBInfo.AUTHORITY, "my_tbl/#", SINGLE_ROW);
}
@Override
public boolean onCreate() {
System.out.println("MyContentProvider ---> onCreate()");
dbHelper = new DatabaseHelper(getContext());
return false;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int resultCode = db.delete(DBInfo.TABLE_NAME, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return resultCode;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case ALL_ROWS:
return DBInfo.CONTENT_TYPE;
case SINGLE_ROW:
return DBInfo.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.insert(DBInfo.TABLE_NAME, null, values);
getContext().getContentResolver().notifyChange(uri, null);
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.query(DBInfo.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
}
Activity:
public class Activity01 extends Activity {
private static final int INSERT_TAG = 1;
private static final int DELETE_TAG = 2;
private Uri uri = Uri.parse("content://droid.provider.mycontentprovider/my_tbl");
private EditText name_input;
private Button insertBtn;
private Button deleteBtn;
private TextView display;
private MyObserver observer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name_input = (EditText) findViewById(R.id.name_input);
insertBtn = (Button) findViewById(R.id.insertBtn);
deleteBtn = (Button) findViewById(R.id.deleteBtn);
insertBtn.setOnClickListener(new ButtonListener());
deleteBtn.setOnClickListener(new ButtonListener());
insertBtn.setTag(INSERT_TAG);
deleteBtn.setTag(DELETE_TAG);
display = (TextView) findViewById(R.id.display);
observer = new MyObserver(new Handler());
this.getContentResolver().registerContentObserver(uri, true, observer);
query();
}
private class ButtonListener implements OnClickListener {
@Override
public void onClick(View v) {
int tag = (Integer) v.getTag();
switch(tag) {
case INSERT_TAG:
insert();
break;
case DELETE_TAG:
delete();
break;
}
}
}
private void insert() {
ContentValues cv = new ContentValues();
String nameStr = name_input.getText().toString();
if(nameStr == null || "".equals(nameStr)) {
return;
}
cv.put("name", nameStr);
this.getContentResolver().insert(uri, cv);
}
private void delete() {
String nameStr = name_input.getText().toString();
int i = this.getContentResolver().delete(uri, "name=?", new String[]{nameStr});
System.out.println("--- delete() i--->" + i);
}
private void query() {
String[] projection = {"_id", "name"};
StringBuffer sb = new StringBuffer();;
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
if(cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
for(int i=0; i<cursor.getCount(); i++) {
cursor.moveToPosition(i);
String id = cursor.getString(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
sb.append("id: " + id + " ; name: " + name + "\n");
}
}
display.setText(sb.toString());
sb.delete(0, sb.length());
}
public class MyObserver extends ContentObserver {
public MyObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
System.out.println(" ----- MyObserver -----> onChange() --- selfChange: " + selfChange);
query();
}
}
}
一定记得,contentProvider要在配置文件中声明:
<provider android:authorities="droid.provider.mycontentprovider"
android:name=".MyContentProvider" />
布局很简单,这里就不在贴布局文件了。ContentProvider提供的不够完整。