Android Api Demos登顶之路(六十二)Content-->Change Contacts

从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;
    }

}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fishtosky/article/details/48337819
个人分类: Android ApiDemos
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭