Android 自定义ContentProvider和ContentObserver的完整使用
在自定义ContentProvider结合ContentObserver一起使用时,自己写的ContentProvider,在执行完insert、delete和update后,要手动地调用getContentResolver().notifyChange()这个方法来通知改动的产生。
直接上代码:
MainActivity
<span style="font-family:SimSun;font-size:14px;"><span style="font-family:SimSun;font-size:14px;">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 <span style="color:#ff0000;">//自己写的ContentProvider,在执行完insert、delete和update后,要手动地调用getContentResolver().notifyChange()这个方法来通知改动的产生(请参考MyProvider.java的方法)</span> break; default: break; } return super.onMenuItemSelected(featureId, item); } } </span></span>
<span style="font-family:SimSun;font-size:14px;"><span style="font-family:SimSun;font-size:14px;">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(); } } </span></span>
<span style="font-family:SimSun;font-size:14px;"><span style="font-family:SimSun;font-size:14px;">package 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) { } } </span></span>
MyBaseAdapter.java
<span style="font-family:SimSun;font-size:14px;"><span style="font-family:SimSun;font-size:14px;">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; } }</span></span>
MyProvider.java
<span style="font-family:SimSun;font-size:14px;"><span style="font-family:SimSun;font-size:14px;">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); <span style="color:#ff0000;">//向外界通知该ContentProvider里的数据发生了变化 ,以便ContentObserver作出相应 getContext().getContentResolver().notifyChange(uri, null);</span> 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; } } </span></span>
Person.java
<span style="font-family:SimSun;font-size:14px;"><span style="font-family:SimSun;font-size:14px;">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; } }</span></span>
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。