19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.DataSetObserver;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Adapter that exposes data from a {@link android.database.Cursor Cursor} to a
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.widget.ListView ListView} widget. The Cursor must include
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a column named "_id" or this class will not work.
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class CursorAdapter extends BaseAdapter implements Filterable,
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CursorFilter.CursorFilterClient {
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean mDataValid;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean mAutoRequery;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected Cursor mCursor;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected Context mContext;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected int mRowIDColumn;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected ChangeObserver mChangeObserver;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
69c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    protected DataSetObserver mDataSetObserver;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected CursorFilter mCursorFilter;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected FilterQueryProvider mFilterQueryProvider;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
82451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * If set the adapter will call requery() on the cursor whenever a content change
83c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * notification is delivered. Implies {@link #FLAG_REGISTER_CONTENT_OBSERVER}.
84c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
85c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @deprecated This option is discouraged, as it results in Cursor queries
86c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * being performed on the application's UI thread and thus can cause poor
87c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * responsiveness or even Application Not Responding errors.  As an alternative,
88c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
89451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     */
90c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    @Deprecated
91451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    public static final int FLAG_AUTO_REQUERY = 0x01;
92451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
93451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    /**
94451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * If set the adapter will register a content observer on the cursor and will call
95c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * {@link #onContentChanged()} when a notification comes in.  Be careful when
96c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * using this flag: you will need to unset the current Cursor from the adapter
97c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * to avoid leaks due to its registered observers.  This flag is not needed
98c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * when using a CursorAdapter with a
99c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * {@link android.content.CursorLoader}.
100451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     */
101451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    public static final int FLAG_REGISTER_CONTENT_OBSERVER = 0x02;
102451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
103451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    /**
104c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Constructor that always enables auto-requery.
105c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
106c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @deprecated This option is discouraged, as it results in Cursor queries
107c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * being performed on the application's UI thread and thus can cause poor
108c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * responsiveness or even Application Not Responding errors.  As an alternative,
109c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param c The cursor from which to get the data.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
114c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    @Deprecated
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CursorAdapter(Context context, Cursor c) {
116451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        init(context, c, FLAG_AUTO_REQUERY);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
120c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Constructor that allows control over auto-requery.  It is recommended
121c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * you not use this, but instead {@link #CursorAdapter(Context, Cursor, int)}.
122c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * When using this constructor, {@link #FLAG_REGISTER_CONTENT_OBSERVER}
123c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * will always be set.
124c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param c The cursor from which to get the data.
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param autoRequery If true the adapter will call requery() on the
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    cursor whenever it changes so the most recent
129c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *                    data is always displayed.  Using true here is discouraged.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CursorAdapter(Context context, Cursor c, boolean autoRequery) {
13269e87f9b43b82b9a0f8a0fbc1c41251bbea212f9Jeff Hamilton        init(context, c, autoRequery ? FLAG_AUTO_REQUERY : FLAG_REGISTER_CONTENT_OBSERVER);
133451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    }
134451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
135451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    /**
136c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Recommended constructor.
137c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
138451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * @param c The cursor from which to get the data.
139451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * @param context The context
140c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @param flags Flags used to determine the behavior of the adapter; may
141c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * be any combination of {@link #FLAG_AUTO_REQUERY} and
142c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * {@link #FLAG_REGISTER_CONTENT_OBSERVER}.
143451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     */
144451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    public CursorAdapter(Context context, Cursor c, int flags) {
145451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        init(context, c, flags);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
148c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    /**
149c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @deprecated Don't use this, use the normal constructor.  This will
150c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * be removed in the future.
151c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     */
152c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    @Deprecated
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void init(Context context, Cursor c, boolean autoRequery) {
15469e87f9b43b82b9a0f8a0fbc1c41251bbea212f9Jeff Hamilton        init(context, c, autoRequery ? FLAG_AUTO_REQUERY : FLAG_REGISTER_CONTENT_OBSERVER);
155451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    }
156451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
157c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    void init(Context context, Cursor c, int flags) {
158451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        if ((flags & FLAG_AUTO_REQUERY) == FLAG_AUTO_REQUERY) {
159451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            flags |= FLAG_REGISTER_CONTENT_OBSERVER;
160451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mAutoRequery = true;
161451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        } else {
162451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mAutoRequery = false;
163451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        }
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean cursorPresent = c != null;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCursor = c;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDataValid = cursorPresent;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
169451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        if ((flags & FLAG_REGISTER_CONTENT_OBSERVER) == FLAG_REGISTER_CONTENT_OBSERVER) {
170451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mChangeObserver = new ChangeObserver();
171c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            mDataSetObserver = new MyDataSetObserver();
172451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        } else {
173451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mChangeObserver = null;
174c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            mDataSetObserver = null;
175451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        }
176451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cursorPresent) {
178451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            if (mChangeObserver != null) c.registerContentObserver(mChangeObserver);
179c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mDataSetObserver != null) c.registerDataSetObserver(mDataSetObserver);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the cursor.
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the cursor.
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Cursor getCursor() {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursor;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getCount()
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1942c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public int getCount() {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCursor.getCount();
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getItem(int)
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2052c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public Object getItem(int position) {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.moveToPosition(position);
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCursor;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getItemId(int)
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2172c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public long getItemId(int position) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCursor.moveToPosition(position)) {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mCursor.getLong(mRowIDColumn);
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasStableIds() {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getView(int position, View convertView, ViewGroup parent) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mDataValid) {
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("this should only be called when the cursor is valid");
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mCursor.moveToPosition(position)) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("couldn't move cursor to position " + position);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View v;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (convertView == null) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v = newView(mContext, mCursor, parent);
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v = convertView;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bindView(v, mContext, mCursor);
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return v;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getDropDownView(int position, View convertView, ViewGroup parent) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid) {
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.moveToPosition(position);
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View v;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (convertView == null) {
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = newDropDownView(mContext, mCursor, parent);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = convertView;
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bindView(v, mContext, mCursor);
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return v;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Makes a new view to hold the data pointed to by cursor.
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent The parent to which the new view is attached to
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the newly created view.
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract View newView(Context context, Cursor cursor, ViewGroup parent);
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Makes a new drop down view to hold the data pointed to by cursor.
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent The parent to which the new view is attached to
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the newly created view.
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return newView(context, cursor, parent);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Bind an existing view to the data pointed to by cursor
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param view Existing view, returned earlier by newView
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void bindView(View view, Context context, Cursor cursor);
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the underlying cursor to a new cursor. If there is an existing cursor it will be
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * closed.
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
306c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @param cursor The new cursor to be used
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void changeCursor(Cursor cursor) {
309c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        Cursor old = swapCursor(cursor);
310c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        if (old != null) {
311c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            old.close();
312c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        }
313c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    }
314c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn
315c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    /**
316c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Swap in a new Cursor, returning the old Cursor.  Unlike
317c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
318c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * closed.
319c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
320c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @param newCursor The new cursor to be used.
321c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @return Returns the previously set Cursor, or null if there wasa not one.
322c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * If the given new Cursor is the same instance is the previously set
323c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Cursor, null is also returned.
324c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     */
325c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    public Cursor swapCursor(Cursor newCursor) {
326c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        if (newCursor == mCursor) {
327c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            return null;
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
329c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        Cursor oldCursor = mCursor;
330c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        if (oldCursor != null) {
331c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mChangeObserver != null) oldCursor.unregisterContentObserver(mChangeObserver);
332c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mDataSetObserver != null) oldCursor.unregisterDataSetObserver(mDataSetObserver);
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
334c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        mCursor = newCursor;
335c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        if (newCursor != null) {
336c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mChangeObserver != null) newCursor.registerContentObserver(mChangeObserver);
337c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mDataSetObserver != null) newCursor.registerDataSetObserver(mDataSetObserver);
338c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = true;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // notify the observers about the new cursor
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetChanged();
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRowIDColumn = -1;
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = false;
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // notify the observers about the lack of a data set
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetInvalidated();
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
348c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        return oldCursor;
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Converts the cursor into a CharSequence. Subclasses should override this
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method to convert their results. The default implementation returns an
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * empty String for null values or the default String representation of
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the value.</p>
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor the cursor to convert to a CharSequence
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a CharSequence representing the value
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence convertToString(Cursor cursor) {
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return cursor == null ? "" : cursor.toString();
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs a query with the specified constraint. This query is requested
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the filter attached to this adapter.
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The query is provided by a
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.widget.FilterQueryProvider}.
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If no provider is specified, the current cursor is not filtered and returned.
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * After this method returns the resulting cursor is passed to {@link #changeCursor(Cursor)}
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and the previous cursor is closed.
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method is always executed on a background thread, not on the
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application's main thread (or UI thread.)
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Contract: when constraint is null or empty, the original results,
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * prior to any filtering, must be returned.
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param constraint the constraint with which the query must be filtered
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a Cursor representing the results of the new query
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilter()
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilterQueryProvider()
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mFilterQueryProvider != null) {
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mFilterQueryProvider.runQuery(constraint);
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursor;
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Filter getFilter() {
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCursorFilter == null) {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursorFilter = new CursorFilter(this);
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursorFilter;
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the query filter provider used for filtering. When the
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider is null, no filtering occurs.
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the current filter query provider or null if it does not exist
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #runQueryOnBackgroundThread(CharSequence)
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public FilterQueryProvider getFilterQueryProvider() {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFilterQueryProvider;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the query filter provider used to filter the current Cursor.
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The provider's
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.widget.FilterQueryProvider#runQuery(CharSequence)}
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method is invoked when filtering is requested by a client of
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this adapter.
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param filterQueryProvider the filter query provider or null to remove it
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilterQueryProvider()
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #runQueryOnBackgroundThread(CharSequence)
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFilterQueryProvider(FilterQueryProvider filterQueryProvider) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFilterQueryProvider = filterQueryProvider;
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the {@link ContentObserver} on the cursor receives a change notification.
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The default implementation provides the auto-requery logic, but may be overridden by
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sub classes.
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see ContentObserver#onChange(boolean)
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onContentChanged() {
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
44243a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato            if (false) Log.v("Cursor", "Auto requerying " + mCursor + " due to update");
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = mCursor.requery();
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class ChangeObserver extends ContentObserver {
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ChangeObserver() {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(new Handler());
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean deliverSelfNotifications() {
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onChange(boolean selfChange) {
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onContentChanged();
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class MyDataSetObserver extends DataSetObserver {
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onChanged() {
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = true;
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetChanged();
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onInvalidated() {
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = false;
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetInvalidated();
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
478