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
原创粉丝点击