Android Api Demos登顶之路(六十二)Content-->Change Contacts
来源:互联网 发布:mysql with查询 编辑:程序博客网 时间:2024/05/19 10:55
从API18开始,在Contact表中,新加了CONTACT_LAST_UPDATED_TIMESTAMP列,
* 表示该contact被更新的时间。
* 这个demo就演示了如何通过读取该列的值,获取某个时间段内对contact所做的修改。
* 在本例中使用了LoaderManager,前面我们已经学习了这个类,今天我们再来加深一下理解:
* LoaderManager用来负责管理与Activity或者Fragment联系起来的一个或多个Loaders对象。
* 每个Activity或者Fragment都有唯一的一个LoaderManager实例,用来启动、停止、保持、重启、
* 关闭它的Loaders。这些事件有时直接在客户端通过调用
* initLoader()/restartLoader()/destroyLoader()函数来实现。
* 那么,LoaderManager是如何实现对Loader的管理的呢?是通过LoaderCallBacks接口来实现的。
* 实现这个接口就要实现三个方法:ononCreateLoader()用于创建loader,onLoadFinished用于
* 在loader加载完毕时执行某些操作。onLoaderReset(),用于设置在loader重置时执行的一些操作。
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:id="@+id/update"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:id="@+id/delete"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/display_result" /> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/listView"></ListView></LinearLayout>
MainActivity
public class MainActivity extends Activity implements LoaderCallbacks<Cursor> { private static final int ID_DELETE_LOADER = 2; private static final int ID_UPDATE_LOADER = 1; private static final String PREF_KEY_CHANGE = "timestamp_changed"; private static final String PREF_KEY_DELETE = "timestamp_delete"; private static final String CLASS = "MainActivity"; private TextView mDisplayResult; private ListView mList; private LoaderManager mLM; // 定义listView的适配器 private ChangeAdapter mAdapter; private DeleteAdapter mDeleteAdapter; private long msearchTime; private Button update; private Button delete; /* * 定义一个广播接收者用于处理当接收到创建联系人数据库时的操作。 * 当我们在设置-应用-联系人存储当中点击清除数据时,会将联系人的数据库清除 * 此时我们点击任意一个按钮都会先创建数据库 */ private BroadcastReceiver mReceive=new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(MainActivity.this, "数据库被创建了!", 0).show(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLM = getLoaderManager(); mAdapter = new ChangeAdapter(this, null, 0); mDeleteAdapter = new DeleteAdapter(this,null,0); mDisplayResult = (TextView) findViewById(R.id.display_result); mList = (ListView) findViewById(R.id.listView); update = (Button) findViewById(R.id.update); delete = (Button) findViewById(R.id.delete); update.setText("Change Since" + getLastTimeStamp(PREF_KEY_CHANGE, 0)); delete.setText("Delete Since" + getLastTimeStamp(PREF_KEY_DELETE, 0)); update.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { updateClick(); } }); delete.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { deleteClick(); } }); } @Override protected void onResume() { super.onResume(); IntentFilter filter=new IntentFilter(); filter.addAction(ContactsContract.Intents.CONTACTS_DATABASE_CREATED); registerReceiver(mReceive, filter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(mReceive); } protected void deleteClick() { // 首先清空适配器中的数据 mDeleteAdapter.swapCursor(null); // 移除updateLoader,因为我们在对该按钮的点击事件的处理过程中与updateLoader无关 mLM.destroyLoader(ID_UPDATE_LOADER); // 重新启动updateLoader,让Activity实现LoaderCallBacks接口 mLM.restartLoader(ID_DELETE_LOADER, null, this); } /* * 点击按钮时查询一定时间段内对contact所作的修改操作 */ protected void updateClick() { // 首先清空适配器中的数据 mAdapter.swapCursor(null); // 移除deleteLoader,因为我们在对该按钮的点击事件的处理过程中与deleteLoader无关 mLM.destroyLoader(ID_DELETE_LOADER); // 重新启动updateLoader,让Activity实现LoaderCallBacks接口 mLM.restartLoader(ID_UPDATE_LOADER, null, this); } // 根据Id获取相应的Loader实例 @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { switch (id) { case ID_UPDATE_LOADER: return getUpdateLoader(); case ID_DELETE_LOADER: return getDeleteLoader(); } return null; } private Loader<Cursor> getUpdateLoader() { // 定义要查询的列 String[] projection = new String[] { ContactsContract.Data._ID, ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP }; msearchTime = getLastTimeStamp(PREF_KEY_CHANGE, 0); // 设置查询条件,以从sharedpreferences当中取出的时间作为开始时间,数据表中最近一次 // 修改contact的时间作为结束时间,查询这段时间内对contact修改的记录。 String selection = ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP + " > ?"; // 定义查询的参数(代替?通配符) String[] bindArgs = new String[] { msearchTime + "" }; return new CursorLoader(this, ContactsContract.Data.CONTENT_URI, projection, selection, bindArgs, ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP + " desc, " + ContactsContract.Data.CONTACT_ID + " desc"); } private long getLastTimeStamp(String key, long time) { SharedPreferences pref = getSharedPreferences(CLASS, Context.MODE_PRIVATE); return pref.getLong(key, time); } private Loader<Cursor> getDeleteLoader() { String[] projection = new String[] { ContactsContract.DeletedContacts.CONTACT_ID, ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP }; msearchTime = getLastTimeStamp(PREF_KEY_DELETE, 0); // 设置查询条件,以从sharedpreferences当中取出的时间作为开始时间,数据表中最近一次 // 修改contact的时间作为结束时间,查询这段时间内对contact修改的记录。 String selection = ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP + " > ?"; // 定义查询的参数(代替?通配符) String[] bindArgs = new String[] { msearchTime + "" }; return new CursorLoader(this, ContactsContract.DeletedContacts.CONTENT_URI, projection, selection, bindArgs, ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP + " desc"); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { long timeStamp = 0; switch (loader.getId()) { case ID_UPDATE_LOADER: // 为textView设置文本 mDisplayResult.setText(data.getCount() + "Change(s) Since" + msearchTime); // 设置适配器 mAdapter.swapCursor(data); mList.setAdapter(mAdapter); // 如果查询的结果集不为空,则取出第一条记录,即为最近一次修改的记录,因为我们设置了按降序排序 if (data.moveToNext()) { timeStamp = data .getLong(data .getColumnIndex(ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP)); data.moveToPrevious(); } if (timeStamp > 0) { // 将该时间保存到sharepreferences当中 saveLastTimeStamp(PREF_KEY_CHANGE, timeStamp); // 设置按钮的文本 update.setText("Changed Since" + timeStamp); } break; case ID_DELETE_LOADER: // 为textView设置文本 mDisplayResult.setText(data.getCount() + "Delete(s) Since" + msearchTime); // 设置适配器 mDeleteAdapter.swapCursor(new DeleteCursorWrapper(data)); mList.setAdapter(mAdapter); // 如果查询的结果集不为空,则取出第一条记录,即为最近一次修改的记录,因为我们设置了按降序排序 if (data.moveToNext()) { timeStamp = data .getLong(data .getColumnIndex(ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP)); data.moveToPrevious(); } if (timeStamp > 0) { // 将该时间保存到sharepreferences当中 saveLastTimeStamp(PREF_KEY_DELETE, timeStamp); // 设置按钮的文本 delete.setText("Delete Since" + timeStamp); } break; } } @Override public void onLoaderReset(Loader<Cursor> loader) { switch (loader.getId()) { case ID_UPDATE_LOADER: mAdapter.swapCursor(null); break; case ID_DELETE_LOADER: mDeleteAdapter.swapCursor(null); break; } } private void saveLastTimeStamp(String key, long time) { SharedPreferences pref = getSharedPreferences(CLASS, Context.MODE_PRIVATE); SharedPreferences.Editor editor = pref.edit(); editor.putLong(PREF_KEY_CHANGE, time); editor.commit(); } //CursorWrapper只是简单实现了Cursor接口,是直接对Cursor接口的包装而没有干其他事情 //方便我们实现某些方法实现功能的扩展 private class DeleteCursorWrapper extends CursorWrapper{ public DeleteCursorWrapper(Cursor cursor) { super(cursor); } @Override public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException { //如果发现不是ContactsContract.DeletedContacts.CONTACT_ID,则转化过来 if(columnName.equals("_id")){ return super.getColumnIndex(ContactsContract.DeletedContacts.CONTACT_ID); } return super.getColumnIndexOrThrow(columnName); } } private class ChangeAdapter extends CursorAdapter { public ChangeAdapter(Context context, Cursor c, int flags) { super(context, c, flags); } // 创建并设置UI界面 @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { LinearLayout item = new LinearLayout(context); item.addView(buildTextView(context)); item.addView(buildTextView(context)); item.addView(buildTextView(context)); return item; } // 为界面中的组件绑定数据 @Override public void bindView(View view, Context context, Cursor cursor) { LinearLayout item = (LinearLayout) view; String id = cursor.getString(cursor .getColumnIndex(ContactsContract.Data.CONTACT_ID)); String name = cursor.getString(cursor .getColumnIndex(ContactsContract.Data.DISPLAY_NAME)); String timeStamp = cursor .getString(cursor .getColumnIndex(ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP)); setText(item.getChildAt(0), id); setText(item.getChildAt(1), name); setText(item.getChildAt(2), timeStamp); } } private class DeleteAdapter extends CursorAdapter { public DeleteAdapter(Context context, Cursor c, int flags) { super(context, c, flags); } // 创建并设置UI界面 @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { LinearLayout item = new LinearLayout(context); item.addView(buildTextView(context)); item.addView(buildTextView(context)); return item; } // 为界面中的组件绑定数据 @Override public void bindView(View view, Context context, Cursor cursor) { LinearLayout item = (LinearLayout) view; String id = cursor.getString(cursor .getColumnIndex(ContactsContract.DeletedContacts.CONTACT_ID)); String timeStamp = cursor .getString(cursor .getColumnIndex(ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP)); setText(item.getChildAt(0), id); setText(item.getChildAt(2), timeStamp); } } public void setText(View view, String text) { TextView tv = (TextView) view; tv.setText(text); } public View buildTextView(Context context) { TextView view = new TextView(context); view.setPadding(3, 3, 3, 3); return view; }}
0 0
- Android Api Demos登顶之路(六十二)Content-->Change Contacts
- Android Api Demos登顶之路(十四)Quick Contacts
- Android Api Demos登顶之路(五十九)Content-->Assets
- Android Api Demos登顶之路(六十)Content-->ClipBoard
- Android Api Demos登顶之路(六十一)Content-->PickContacts
- Android Api Demos登顶之路(100)View-->AutoComplete:Contacts
- Android Api Demos登顶之路(六十三)Content-->Resources Smallest Width
- Android Api Demos登顶之路(六十四)Content-->External Storage
- Android Api Demos登顶之路(二)
- Android Api Demos登顶之路(三)
- Android Api Demos登顶之路(四)
- Android Api Demos登顶之路(五)
- Android Api Demos登顶之路(六)
- Android Api Demos登顶之路(七)
- Android Api Demos登顶之路(八)
- Android Api Demos登顶之路(九)
- Android Api Demos登顶之路(十)Overscan
- Android Api Demos登顶之路(十一)Persistent state
- Code more
- iOS --- UIViewController中的loadView使用场景
- iOS开发之UITableView全面解析
- icomet在项目中使用
- 【C#】课程设计——贪吃蛇(可调节蛇的速度)
- Android Api Demos登顶之路(六十二)Content-->Change Contacts
- Java学习笔记(一)JDK的安装与环境配置
- Javascript邮件管理
- 反射与正则表达式
- 处理EBS采购申请单无法审批的问题
- Android studio 新建项目\values-v23\values-v23.xml报错
- javascript验证
- static 和 final
- ajax2用户名检测