Android 自定義ContentProvider和ContentObserver的完整使用
阿新 • • 發佈:2019-02-19
在自定義ContentProvider結合ContentObserver一起使用時,自己寫的ContentProvider,在執行完insert、delete和update後,要手動地呼叫getContentResolver().notifyChange()這個方法來通知改動的產生。
直接上程式碼:
MainActivity
package com.jackie.contentobserver; import java.util.ArrayList; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends Activity { private ArrayList<Person> mList; private ListView mListView; private ContentResolver resolver; private MyBaseAdapter mBaseAdapter; private Handler mHandler; private AdapterContentObserver mAdapterContentObserver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.lv_person); initData(); mBaseAdapter = new MyBaseAdapter(this, mList); mListView.setAdapter(mBaseAdapter); mHandler = new Handler(); mAdapterContentObserver = new AdapterContentObserver(this, mHandler); resolver.registerContentObserver(Uri.parse("content://com.jackie.provider.person/person"), true, mAdapterContentObserver); //註冊簡訊變化監聽 //this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content) } @Override protected void onDestroy() { resolver.unregisterContentObserver(mAdapterContentObserver); super.onDestroy(); } private ArrayList<Person> initData() { mList = new ArrayList<Person>(); resolver = getContentResolver(); Cursor cursor = resolver.query(Uri.parse("content://com.jackie.provider.person/person"), null, null, null, null); while (cursor.moveToNext()) { Person person = new Person(); person.set_id(cursor.getInt(cursor.getColumnIndex("_id"))); person.setName(cursor.getString(cursor.getColumnIndex("name"))); mList.add(person); } return mList; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case R.id.menu_settings: // AlertDialog.Builder builder = new AlertDialog.Builder(this); // builder.setTitle("提示").setMessage("您確定要退出?"); // builder.create().show(); ContentValues values = new ContentValues(); values.put("name", "Jackie"); Uri mUri = resolver.insert(Uri.parse("content://com.jackie.provider.person/person"), values); //方法一: 重新查詢資料庫實時重新整理 // mBaseAdapter = new MyBaseAdapter(this, initData()); // mListView.setAdapter(mBaseAdapter); //方法二: 當adapter繫結的list變化時,呼叫adapter的notifyDataSetChanged方法實時重新整理(不用重複查詢資料庫,效率更高) // long id = ContentUris.parseId(mUri); // mList.add(new Person(id, "chengjie")); // mBaseAdapter.notifyDataSetChanged(); //方法三: 內容觀察者ContentObserver //自己寫的ContentProvider,在執行完insert、delete和update後,要手動地呼叫getContentResolver().notifyChange()這個方法來通知改動的產生(請參考MyProvider.java的方法) break; default: break; } return super.onMenuItemSelected(featureId, item); } }
AdapterContentObserver.java
package com.jackie.contentobserver; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.util.Log; import android.widget.Toast; public class AdapterContentObserver extends ContentObserver { private Context context; private Handler handler; private static final int PERSON_UPDATE = 0; public AdapterContentObserver(Handler handler) { super(handler); // TODO Auto-generated constructor stub } public AdapterContentObserver(Context context, Handler handler) { super(handler); this.context = context; this.handler = handler; } //當監聽的Uri發生變化,便會執行這個方法 @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); ContentResolver resolver = context.getContentResolver(); // 獲取最新的一條資料 Cursor cursor = resolver.query(uri, null, null, null, "_id desc limit 1"); while (cursor.moveToNext()) { int _id = cursor.getInt(cursor.getColumnIndex("_id")); Toast.makeText(context, "資料庫更新了, _id 為: " + _id, Toast.LENGTH_SHORT).show(); } cursor.close(); } }
DBHelper.java
MyBaseAdapter.javapackage com.jackie.contentobserver; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class DBHelper extends SQLiteOpenHelper { 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) { db.execSQL("create table if not exists person(_id integer primary key autoincrement, name text)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
package com.jackie.contentobserver;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyBaseAdapter extends BaseAdapter {
private ViewHolder holder;
private Context context;
private ArrayList<Person> mList;
public MyBaseAdapter(Context context, ArrayList<Person> mList) {
this.context = context;
this.mList = mList;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater mInflater = LayoutInflater.from(context);
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.listview_item, null);
holder.idTexitView = (TextView) convertView.findViewById(R.id.tv_id);
holder.nameTextView = (TextView) convertView.findViewById(R.id.tv_name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.idTexitView.setText(mList.get(position).get_id() + "");
holder.nameTextView.setText(mList.get(position).getName());
return convertView;
}
class ViewHolder {
TextView idTexitView;
TextView nameTextView;
}
}
MyProvider.java
package com.jackie.contentobserver;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public class MyProvider extends ContentProvider {
private final static String AUTHORITH = "com.jackie.provider.person";
private final static String PERSONS_PATH = "person";
private final static String PERSON_PATH = "person/#";
private final static int PERSON = 1;
private final static int PERSONS = 2;
private final static String DATABASE_NAME = "person_db";
private final static String TABLE_NAME = "person";
private final static String TABLE_COLUMN_ID = "_id";
private final static String TABLE_COLUMN_NAME = "name";
private final static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
mUriMatcher.addURI(AUTHORITH, PERSONS_PATH, PERSONS);
mUriMatcher.addURI(AUTHORITH, PERSON_PATH, PERSON);
}
private DBHelper helper = null;
@Override
public boolean onCreate() {
helper = new DBHelper(getContext(), DATABASE_NAME, null, 1);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase database = helper.getWritableDatabase();
switch (mUriMatcher.match(uri)) {
case PERSON:
long id = ContentUris.parseId(uri);
String where = TABLE_COLUMN_ID + "=" + id;
if (selection != null && !"".equals(selection)) {
selection = where + "and" + selection;
}
return database.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
case PERSONS:
return database.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
default:
throw new IllegalArgumentException("UnKnown uri: " + uri);
}
}
@Override
public String getType(Uri uri) {
switch (mUriMatcher.match(uri)) {
case PERSON:
return "vnd.android.cursor.item";
case PERSONS:
return "vnd.android.cursor.dir";
default:
throw new IllegalArgumentException("UnKnown uri: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase database = helper.getWritableDatabase();
long id = database.insert(TABLE_NAME, TABLE_COLUMN_NAME, values);
//向外界通知該ContentProvider裡的資料發生了變化 ,以便ContentObserver作出相應
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(uri, id);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase database = helper.getWritableDatabase();
switch (mUriMatcher.match(uri)) {
case PERSON:
long id = ContentUris.parseId(uri);
String where = TABLE_COLUMN_ID + "=" + id;
if (selection != null && !"".equals(selection)) {
selection = where + "and" + selection;
}
return database.delete(TABLE_NAME, selection, selectionArgs);
case PERSONS:
return database.delete(TABLE_NAME, selection, selectionArgs);
default:
throw new IllegalArgumentException("UnKnown uri: " + uri);
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
}
Person.java
package com.jackie.contentobserver;
public class Person {
private long _id;
private String name;
public Person(long _id, String name) {
super();
this._id = _id;
this.name = name;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
public long get_id() {
return _id;
}
public void set_id(long _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}